<template>
  <div class="table_div">
    <table
      :id="tableId ? tableId : 'tableId'"
      class="table_style bill_mask_back_view"
      @focusin="gridOnFocus"
      @focusout="gridOnBlur"
      @keydown="gridOnKeyDown"
      @keyup="gridOnKeyUp"
      @resize="tblresize"
      cellspacing="0"
      cellpadding="0"
      style="border-spacing: 0"
    >
      <thead>
        <tr class="first_tr">
          <th
            v-for="(item, index) in TableConfig.columnData"
            :key="index"
            style="position: relative"
            :id="item.props"
            :style="{
              width: item.cellWidth || '150px',
              display: !item.isShow || !item.zidingyiState ? 'none' : '',
            }"
          >
            <div v-if="item.morenName == '条形码'" style="display: flex; justify-content: center; align-items: center">
              <span v-if="item.zidingyiName">{{ item.zidingyiName }}</span>
              <div v-else style="display: flex; align-items: center">
                <img src="@assets/bill_scan.png" />
                <span style="color: #0089ff; margin-left: 5px; font-size: 12px">扫码</span>
              </div>
            </div>
            <div v-else-if="item.morenName == '送货数量' && billName === '销售出库'">
              <p style="color: #0077ff; cursor: pointer" @click="handleDeliverGoodsNumber">
                {{ item.zidingyiName ? item.zidingyiName : item.morenName }}
              </p>
            </div>
            <template v-else-if="item.props.includes('extendValue') && !billDisabled">
              <el-input
                v-if="item.editHeader"
                v-model="item.zidingyiName"
                size="mini"
                placeholder="请输入"
                maxlength="10"
                style="padding-left: 3px"
              >
                <div slot="suffix" style="color: #1c94fa; line-height: 28px" @click="onSaveExtend(item)">保存</div>
              </el-input>
              <div
                v-else
                style="width: 100%; display: flex; justify-content: space-between; align-items: center; padding: 0 10px"
              >
                <span>{{ item.zidingyiName || item.morenName }}</span>
                <img
                  :src="require('@/assets/extend_edit.png')"
                  style="width: 12px; height: 12px"
                  @click="item.editHeader = true"
                />
              </div>
            </template>
            <template v-else>
              <p v-if="item.isRequired">
                <span class="star">*</span>
                {{ item.zidingyiName ? item.zidingyiName : item.morenName }}
              </p>
              <p v-else>{{ item.zidingyiName ? item.zidingyiName : item.morenName }}</p>
            </template>
            <div v-if="(item.isShow || item.zidingyiState) && tableCount == 1" class="resizer" id="resizer"></div>
          </th>
        </tr>
      </thead>
      <tbody>
        <tr
          v-for="(item, index) in TableConfig.tableData"
          :key="index"
          :class="showbackGroundStyle == index && !billDisabled ? 'active_backGround' : ''"
          @focusin="showbackGroundStyle = index"
          @mousemove="showbackGroundStyle = index"
          @mouseleave="showbackGroundStyle = -1"
        >
          <!-- <div v-if="billDisabled" class="bill_mask_view"></div> -->
          <td
            v-for="(v, k) in TableConfig.columnData"
            :key="k"
            :style="{
              minWidth: v.cellWidth ? v.cellWidth : '120px',
              width: v.cellWidth ? v.cellWidth : '120px',
              display: !v.isShow || !v.zidingyiState ? 'none' : '',
            }"
            :class="v.isShow ? 'tdDom' : ''"
          >
          <div v-if="billDisabled && !(item.specialColorSize && k == 'numberShow')" class="bill_mask_view" style="right: 0;"></div>
            <template v-if="k == 'idx'">
              <div class="first_td input-field">
                <div v-if="showbackGroundStyle == index && !billDisabled" class="first_td_button">
                  <i @click.stop="addRow($event, index)" class="el-icon-circle-plus-outline"></i>
                  <i
                    v-if="billName !== '进项发票信息'"
                    @click.stop="copyRow($event, index)"
                    class="el-icon-document-copy"
                    style="color: #2a9cfb"
                  ></i>
                  <i @click="deleteRow(index)" class="el-icon-remove-outline"></i>
                </div>
                <p class="first_td_p" v-else>{{ index + 1 }}</p>
              </div>
            </template>
            <template v-else-if="v.props === 'formula'">
              <div
                style="width: 100%; display: flex; padding: 0 5px"
                :style="item[k] && item[k].length > 0 ? 'justify-content: space-between;' : 'justify-content: center;'"
                class="input-field"
              >
                <div class="singleLine" v-if="item[k] && item[k].length > 0">{{ item[k] }}</div>
                <div style="color: #1a93fa; cursor: pointer; margin: 0 5px; flex-shrink: 0" @click="onSetFormula(item)" v-if="!isFromBill">
                  设置
                </div>
              </div>
            </template>
            <template v-else-if="v.props === 'formulaId'">
              <div style="margin: 1px; border: 1px solid #dcdfe6; background-color: white; height: 28px">
                <el-select
                  :disabled="isFromBill"
                  @visible-change="handleVisibleChange"
                  :popper-append-to-body="false"
                  v-model="item[k]"
                  @change="(value) => formulaChange(value, item, index)"
                  style="width: 100%"
                  clearable
                  class="input-field"
                >
                  <el-option v-for="(a, b) in item.formulaList" :key="b" :label="a.name" :value="a.id"></el-option>
                  <el-option key label value>
                    <div
                      style="height: 30px; line-height: 30px; text-align: center; color: #1a93fa; cursor: pointer"
                      @click.stop="onAddFormula(item)"
                    >
                      新增
                    </div>
                  </el-option>
                  <!-- <div slot="empty" style="height: 30px;line-height: 30px;text-align: center;color: #1A93FA;cursor: pointer;"  @click="onAddFormula(item)">
                  新增
                </div> -->
                </el-select>
              </div>
            </template>
            <template v-else-if="v.props.includes('extendField') || v.props.includes('extendValue')">
              <p
                :style="{ width: v.cellWidth ? parseInt(v.cellWidth) - 2 + 'px' : '120px' }"
                style="overflow: hidden; text-overflow: ellipsis; white-space: nowrap"
                class="input-field"
              >
                {{ item[k] }}
              </p>
            </template>
            <template v-else-if="v.showType === 'table'">
              <div
                style="width: 100%; height: 100%; display: flex; align-items: center; justify-content: space-between"
              >
                <input
                  type="text"
                  v-model="item[k]"
                  style="
                    border-color: #1893fc;
                    background: transparent;
                    /* width: 260px; */
                    white-space: normal;
                    word-wrap: break-word;
                    overflow: hidden;
                    text-overflow: ellipsis;
                    display: -webkit-box;
                    -webkit-line-clamp: 2;
                    -webkit-box-orient: vertical;
                    text-align: left;
                  "
                  @focus="onShowCommodity(index)"
                  placeholder="请选择"
                  class="input-field"
                />
                <p class="click_p" @click="onShowCommodity(index)">选择</p>
              </div>
            </template>
            <template v-else-if="v.showType === 'selectDw'">
              <el-select
                :disabled="isFromBill"
                v-model="item[k]"
                @change="(value) => dwChange(value, item, index)"
                style="width: 100%"
                class="input-field"
              >
                <el-option v-for="(a, b) in item.unitList" :key="b" :label="a.unit" :value="a.unit"></el-option>
              </el-select>
            </template>
            <template v-else-if="v.showType === 'selectCk'">
              <el-select
                :disabled="isFromBill"
                v-model="item[k]"
                @change="(value) => changeCK(value, item, index)"
                style="width: 100%"
                class="input-field"
              >
                <el-option v-for="a in StorehouseList" :key="a.id" :label="a.storehouseName" :value="a.id"></el-option>
              </el-select>
              <!-- <input type="text" v-model="item[k]" @click="onShowCk(index)" />
              <i class="el-icon-arrow-down select_input"></i>
              <ul class="select_option_ck">
                <li
                  :class="selectLiCk == b ? 'select_li' : ''"
                  v-for="(a, b) in StorehouseList"
                  :key="b"
                  @click="onClickCk(a, b, index)"
                >{{ a.storehouseName }}</li>
              </ul>-->
            </template>
            <template v-else-if="v.showType === 'date'">
              <el-date-picker
                v-model="item[k]"
                type="date"
                value-format="yyyy-MM-dd"
                class="input-field"
              ></el-date-picker>
              <!-- <input type="date"  v-model="item[k]" style="width: 120px" /> -->
            </template>
            <template v-else-if="v.showType === 'check'">
              <input
                :disabled="isFromBill"
                type="checkbox"
                v-model="item[k]"
                @change="onHandleIsGive(item[k], index)"
                class="inpu_checkbox input-field"
              />
            </template>
            <template v-else-if="v.showType === 'input'">
              <p v-if="item.specialColorSize && k == 'numberShow'" style="height: 100%;display: flex;align-items: center;cursor: pointer;" @click="onShowSpecialColorSize(index)">{{ item[k] }}</p>
              <input
                placeholder="请输入"
                type="number"
                v-model="item[k]"
                v-else-if="k === 'numberShow'"
                @blur="handleNumber(index)"
                :min="0"
                @input="inputNumber(k, item)"
                @focus="focusSelect"
                class="input-field"
              />
              <template v-else-if="k === 'salePriceShow'">
                <el-popover
                  v-if="costPerms"
                  placement="top"
                  width="200"
                  trigger="manual"
                  v-model="item.visible"
                  class="pop"
                >
                  <div>
                    <div
                      class="price_item"
                      v-for="(pitem, pindex) in tipPriceList.listData"
                      :key="pindex"
                      @click="setSalePrice(item, k, pitem.val || 0, index)"
                    >
                      <div class="price_text">{{ pitem.priorityName }}</div>
                      <div class="price_value">{{ pitem.val || 0 }}</div>
                    </div>
                  </div>
                  <el-input
                    :disabled="isFromBill"
                    slot="reference"
                    type="text"
                    v-model="item[k]"
                    onkeyup="value=value.replace(/[^\d.]/g,'')"
                    @focus="focusPrice($event, index, null, true)"
                    @blur="handlePriceBlur(index)"
                    @input="inputPrice(k, item)"
                    placeholder="请输入"
                    class="input-field"
                  />
                </el-popover>
                <div v-else style="color: #ff6c00; font-size: 18px" class="input-field">***</div>
              </template>
              <input
                :disabled="isFromBill"
                placeholder="请输入"
                type="number"
                v-model="item[k]"
                v-else-if="k === 'deliverNum'"
                :min="0"
                @blur="handleDeliverGoodsNumberBlur(index)"
                @input="inputNumber(k, item)"
                :style="{ color: item[k] == 0 ? 'red' : '' }"
                class="input-field"
              />
              <template v-else-if="k === 'discountRate'">
                <el-popover placement="top" width="200" trigger="manual" v-model="item.dvisible" class="pop">
                  <div>
                    <div
                      class="price_item"
                      v-for="(pitem, pindex) in tipDiscountList.listData"
                      :key="pindex"
                      @click="setDiscountRate(item, k, pitem.val || 0, index)"
                    >
                      <div class="price_text">{{ pitem.priorityName }}</div>
                      <div class="price_value">{{ pitem.val || 0 }}</div>
                    </div>
                  </div>
                  <el-input
                    :disabled="isFromBill"
                    slot="reference"
                    type="number"
                    v-model="item[k]"
                    onblur="value=value.replace(/[^\d.]/g,'')"
                    @focus="focusDiscountRate($event, index)"
                    @blur="handleDiscountBlur(index)"
                    @input="handleDiscountRate(index)"
                    @keyup="inputPrice(k, item)"
                    placeholder="请输入"
                    class="input-field"
                  />
                </el-popover>
              </template>
              <template v-else-if="k === 'discountUnitPriceShow'">
                <input
                  :disabled="isFromBill"
                  type="text"
                  v-model="item[k]"
                  onkeyup="value=value.replace(/[^\d.]/g,'')"
                  v-if="costPerms"
                  @blur="handleDiscountUnitPrice(index)"
                  @input="inputPrice(k, item)"
                  placeholder="请输入"
                  @focus="focusSelect"
                  class="input-field"
                />
                <div v-else style="color: #ff6c00; font-size: 18px" class="input-field">***</div>
              </template>
              <input
                :disabled="isFromBill"
                type="number"
                v-model="item[k]"
                v-else-if="k === 'taxRate'"
                @blur="handleTaxRate(index)"
                placeholder="请输入"
                @focus="focusSelect"
                class="input-field"
              />
              <template v-else-if="k === 'taxUnitPriceShow'">
                <input
                  :disabled="isFromBill"
                  type="text"
                  v-model="item[k]"
                  onkeyup="value=value.replace(/[^\d.]/g,'')"
                  v-if="costPerms"
                  @blur="handleTaxUnitPrice(index)"
                  @input="inputPrice(k, item)"
                  @focus="focusSelect"
                  class="input-field"
                />
                <div v-else style="color: #ff6c00; font-size: 18px" class="input-field">***</div>
              </template>

              <template v-else-if="k === 'allPriceShow'">
                <input
                  type="text"
                  v-model="item[k]"
                  v-if="costPerms"
                  onkeyup="value=value.replace(/[^\d.]/g,'')"
                  @blur="handleAllPrice(index)"
                  @input="inputMoney(k, item)"
                  placeholder="请输入"
                  @focus="focusSelect"
                  class="input-field"
                />
                <div v-else style="color: #ff6c00; font-size: 18px" class="input-field">***</div>
              </template>

              <template v-else-if="k === 'nowInvoiceAmount'">
                <input
                  :disabled="isFromBill"
                  type="text"
                  v-model="item[k]"
                  onkeyup="value=value.replace(/[^\d.]/g,'')"
                  @blur="handleAllPrice(index)"
                  @input="inputMoney(k, item)"
                  placeholder="请输入"
                  @focus="focusSelect"
                  class="input-field"
                />
              </template>

              <template v-else-if="k === 'remark'">
                <el-tooltip
                  class="item"
                  effect="dark"
                  :content="item[k]"
                  placement="top-end"
                  v-if="item[k] && !remarkFocus"
                >
                  <input
                    :disabled="isFromBill"
                    style="
                      border: 1px solid #ffffff;
                      margin: 0;
                      width: 100%;
                      height: 100%;
                      z-index: 11;
                      position: inherit;
                    "
                    :maxlength="200"
                    type="text"
                    v-model="item[k]"
                    placeholder
                    class="input-field"
                  />
                </el-tooltip>
                <input
                  v-else
                  :disabled="isFromBill"
                  style="border: 1px solid #ffffff; margin: 0; width: 100%; height: 100%"
                  type="text"
                  v-model="item[k]"
                  :maxlength="200"
                  placeholder
                  @focus="remarkFocus = true"
                  @blur="remarkFocus = false"
                  class="input-field"
                />
              </template>
              <input type="text" v-model="item[k]" v-else @blur="updateResultByFormula(index)" class="input-field" />
            </template>
            <template v-else-if="k === 'goodsCode'">
              <p v-if="item.goodsId" style="width: 100%" class="input-field">{{ item[k] }}</p>
              <input
                type="text"
                v-model="item[k]"
                @keyup.enter="handleGoodsCode(index)"
                style="width: 100%"
                placeholder="请输入"
                class="input-field"
                v-else
              />
            </template>
            <template v-else-if="k === 'taxPriceShow'">
              <span v-if="costPerms" class="input-field">{{ item[k] }}</span>
              <div v-else style="color: #ff6c00; font-size: 18px" class="input-field">***</div>
            </template>
            <el-tooltip
              v-else
              effect="dark"
              :content="JSON.stringify(item[k])"
              :enterable="false"
              placement="bottom-start"
            >
              <p
                :style="{ width: v.cellWidth ? parseInt(v.cellWidth) - 2 + 'px' : '120px' }"
                style="overflow: hidden; text-overflow: ellipsis; white-space: nowrap"
                class="input-field"
              >
                {{ item[k] }}
              </p>
            </el-tooltip>
          </td>
        </tr>
      </tbody>
      <tfoot>
        <tr class="last_tr">
          <td
            v-for="(item, index) in TableConfig.columnData"
            :key="index"
            :style="{ minWidth: item.cellWidth, display: !item.isShow || !item.zidingyiState ? 'none' : '' }"
          >
            <p v-if="index == 'idx'">合计</p>
            <p v-if="item.showLength">共{{ TableConfig.tableData.length }}条明细</p>
            <p v-if="item.isSum">{{ item.sumValue ? item.sumValue : 0 }}</p>
          </td>
        </tr>
      </tfoot>
    </table>
    <!-- 选择价格排序弹框 -->
    <div
      class="tip_price_box"
      v-if="tipPriceList.listData.length"
      :style="{
        top: tipPriceList.top + 'px',
        left: tipPriceList.left + 'px',
        display: tipPriceList.displaySta,
      }"
    >
      <table id="tipPriceTable" class="tip_table">
        <tr
          @click="selectMarkPrice(item)"
          v-for="(item, index) in tipPriceList.listData"
          :key="index"
          :class="index == tipPriceList.mark ? 'active_mark' : ''"
        >
          <td>{{ item.name }}</td>
          <td>{{ item.price }}</td>
        </tr>
      </table>
    </div>
    <!-- 选择折扣排序弹框 -->
    <div
      class="tip_price_box"
      v-if="tipDiscountList.listData.length"
      :style="{
        top: tipDiscountList.top + 'px',
        left: tipDiscountList.left + 'px',
        display: tipDiscountList.displaySta,
      }"
    >
      <table id="tipPriceTable" class="tip_table">
        <tr
          @click="selectMarkDiscount(item)"
          v-for="(item, index) in tipDiscountList.listData"
          :key="index"
          :class="index == tipDiscountList.mark ? 'active_mark' : ''"
        >
          <td>{{ item.name }}</td>
          <td>{{ item.price }}</td>
        </tr>
      </table>
    </div>
    <!-- 选择商品弹框 -->
    <DialogCommodity
      ref="commodityRef"
      :storehouseId="activeStorehouseId"
      :companyId="companyId"
      :orderName="orderName"
      :accessType="accessType"
      @onSelectCommodityMultiple="onSelectCommodityMultiple"
    ></DialogCommodity>
    <!-- 选择商品弹框 -->
    <DialogWarehouseGoods ref="dialogWarehouseGoodsRef" @onSelectWarehouseGoods="onSelectWarehouseGoods">
    </DialogWarehouseGoods>
    <!-- 公式 -->
    <dialog-formula ref="formula" @updateFormula="updateFormula"></dialog-formula>
    <!-- 商品特殊功能 -->
    <DialogSpecialColorSize ref="dialogSpecialColorSize" @updateSpecialColorSize="updateSpecialColorSize" @onSpecialClose="onSpecialClose"></DialogSpecialColorSize>
  </div>
</template>

<script>
import DialogCommodity from '@/views/components/dialogCommodity'
import DialogWarehouseGoods from '@/views/components/dialogWarehouseGoods'
import { getAction, postAction } from '@/api/manage'
import DialogFormula from '@/views/components/dialogFormula.vue'
import DialogSpecialColorSize from '@/views/components/dialogSpecialColorSize.vue'
import { handleIsBaseVersion } from '@/utils'
import {
  getSystemParamsByName,
  formatFour,
  formatMoney,
  formatPrice,
  formatNumber,
  delcommafy,
  sysConfig,
  accMul,
  accAdd,
  accSub,
  handleOtherPerms,
} from '@/utils/index'
import { ACCOUNT_BOOK } from '@/store/mutation-types'
import Vue from 'vue'
import { boolean } from 'joi'
export default {
  components: {
    DialogCommodity,
    DialogWarehouseGoods,
    DialogFormula,
    DialogSpecialColorSize,
  },
  props: {
    TableConfig: Object,
    StorehouseList: Array,
    orderName: String,
    billName: String,
    companyId: '',
    accessType: '', //出入库类型
    storehouseId: '',
    tableId: '',
    tableCount: {
      type: Number,
      default: 1,
    },
    billDisabled: {
      type: Boolean,
      default: false,
    },
    isFromBill: {
      type: Boolean,
      default: false
    },
    discountRate: {
      type: [Number, String],
      default: '100',
    },
    taxRate: {
      type: [Number, String],
      default: 0,
    },
    billType: {
      type: String,
      default: '',
    },
  },
  data() {
    return {
      scrollLock: false,
      remarkFocus: false,
      selectLiUnit: -1, //记录当前选中的单位下标
      selectLiCk: -1, //记录当前选中的仓库下标
      showbackGroundStyle: -1, // 记录鼠标移入表格的某一行，改变表格背景色
      tableIndex: 0, // 表格中当前选中第几行的下标
      // tableIndex: -1, // 商品提示框中当前选中第几行的下标
      selecSptListData: {}, // 商品提示框中当前选中第几行的数据
      // 商品提示框数据
      tipSpList: {
        top: 0,
        left: 0,
        displaySta: 'none', //是否显示提示框
        listData: [], //提示框内数据集合
        mark: -1, //激活当前选中行状态
      },
      // 价格列表提示框数据
      tipPriceList: {
        top: 0,
        left: 0,
        displaySta: 'none', //是否显示提示框
        listData: [], //提示框内数据集合
        mark: -1, //激活当前选中行状态
        inputName: '', // 当前输入框的名字
      },
      // 折扣列表提示框数据
      tipDiscountList: {
        top: 0,
        left: 0,
        displaySta: 'none', //是否显示提示框
        listData: [], //提示框内数据集合
        mark: -1, //激活当前选中行状态
        inputName: '', // 当前输入框的名字
      },
      // 传递给新增商品的初始化值
      newData: {
        id: '',
        goodsName: '', //商品名称
        goodsNumber: '', //商品编码
        productionAddress: '', //产地
        goodsNatureId: '1', //商品性质id 1：服务、2.劳务 3.商品（无成本）
        goodsNatureName: '',
        xghGoodsTypeId: '', //商品类别
        xghGoodsTypeName: '',
        costCalculationId: '0', //成本核算
        costCalculationName: '移动加权平均法',
        barCode: '', //条形码
        specs: '', //规格
        defaultUnit: '', //默认单位
        baseUnit: '', //基本单位
        multiPriceStatus: true, //多单位状态 0:开启 1:关闭
        priceStatus: true, //价格管理状态 0:开启 1:关闭
        stockWarningStatus: true, //库存预警状态 0:开启 1:关闭
        distinguishWarning: true, //分库存预警状态 0:开启 1:关闭
        stockStatus: true, //期初库存状态 0:开启 1:关闭
        distinguishBeginning: true, //分期初库存状态 0:开启 1:关闭
        goodsRemark: '', //备注
        manyNormsList: [
          //多单位及价格表数据
          {
            id: '0',
            unitType: '1', //单位类别 1.基本单位2.辅助单位
            unitTypeName: '基本单位',
            unit: '', //单位
            scale: '', //换算比例
            retailPrice: '', //零售价
            barCode: '', //条形码
            specs: '', //规格
            vipPric: '', //会员价
            presetPriceOne: '', //预设售价1
            presetPriceTwo: '', //预设售价2
            presetBidPrice: '', //预设进价
            discountRatioOne: '', //预设折扣1
            discountRatioTwo: '', //预设折扣2
            xhState: true,
          },
        ],
        warningList: [
          //仓库预警数据
          {
            id: '0',
            xghStorehouseId: '', //仓库id
            storehouseName: '总数量预警',
            miniStock: 0, //最低库存
            highStock: 0, //最高库存
            xhState: true,
          },
        ],
        storehouseGoodsList: [
          //分仓库期初数据
          {
            id: '0',
            xghStorehouseId: '', //仓库id
            storehouseName: '',
            beginNumber: '', //期初数量
            beginPrice: '', //期初成本单价
            storePrice: '', //库存金额
            xhState: true,
          },
        ],
      },
      tipTbaleIndex: -1,
      // 价格列表的数据
      priceList: [],
      // 折扣价列表的数据
      dPriceList: [],
      selectSpriceListData: '', // 选中的价格列表数据
      activeStorehouseId: '', //选择商品时对应的仓库
      isAddCommodity: false, // 商品添加成功
      priceLength: 2,
      moneyLength: 2,
      numLength: 2,
      costPerms: false,

      currentRow: 0, // 当前选中的行
      currentCol: 0, // 当前选中的列
      currentInputs: [], // input-field集合

      isBaseVersion: false,
    }
  },
  created() {
    // this.getSubData()
    console.log(this.billType)
    this.costPerms = handleOtherPerms('查看商品成本价及经营数据') || this.billType != 'cgrkd'
    console.log(this.costPerms)
  },
  mounted () {
    this.isBaseVersion = handleIsBaseVersion() 
    this.$nextTick(() => {
      if (this.tableCount == 2) {
        // 换货单有问题，暂未处理
        // this.addDragColumnWidthMore()
      } else {
        this.addDragColumnWidth()
      }
    })
    // document.addEventListener('keyup', (e) => {
    //   // ArrowDown 箭头下 ArrowUp 箭头上 ArrowLeft 箭头左 ArrowRight 箭头右
    //   console.log('keyboard', e.key)
    //   if (e.key === 'ArrowDown') {
    //     if (this.defaultRow == -1) {
    //       this.defaultRow = 0
    //     } else {
    //       console.log(this.TableConfig.tableData.length, this.defaultRow)
    //       if (this.TableConfig.tableData.length > this.defaultRow + 1) {
    //         this.defaultRow++
    //       } else {
    //         console.log(this.TableConfig.tableData.length, this.defaultRow)
    //         this.addRow(this.TableConfig.tableData, this.TableConfig.tableData.length - 1)
    //         this.defaultRow = this.TableConfig.tableData.length - 1
    //       }
    //     }
    //   } else if (e.key === 'ArrowUp') {
    //     if (this.defaultRow == -1) {
    //       this.defaultRow = 0
    //     } else {
    //       if (this.defaultRow > 0) {
    //         this.defaultRow--
    //       }
    //       console.log(this.defaultRow)
    //     }
    //   }
    // })
  },
  computed: {
    allowNegative() {
      return sysConfig().allow_negative_inventory
    },
    isInputManyGoods() {
      return sysConfig().allow_multi_line_entry_goods_info
    },
    PriceTracking() {
      return sysConfig().enable_price_tracking
    },
    discountTracking() {
      return sysConfig().enable_discount_tracking
    },
  },
  watch: {
    'TableConfig.tableData': {
      handler() {
        this.onSum()
      },
      deep: true,
    },
    'TableConfig.columnData': {
      handler() {
        this.onSum()
        this.TableConfig.tableData.forEach((item) => {
          if (!this.billDisabled) {
            if (!item.unitList && !item.goodsManyNorms) {
              this.getManyNormsById(item)
            } else if (!item.unitList) {
              item.unitList = item.goodsManyNorms
            }
          }
        })
      },
      deep: true,
    },
    //  discountRate(val) {
    //    console.log(val)
    //     this.TableConfig.tableData.forEach((item, index) => {
    //       if (item.goodsId) {
    //         this.handlePrice(index)
    //       }
    //    })
    // },
    // taxRate(val) {
    //   console.log(val)
    //   console.log(this.TableConfig.tableData.length);

    //   this.TableConfig.tableData.forEach((item, index) => {
    //     item.taxRate = val
    //     if (item.goodsId) {
    //       this.handlePrice(index)
    //     }
    //   })
    // },
  },
  methods: {
    onShowSpecialColorSize(index) {
      let goods = this.TableConfig.tableData[index]
      if (!goods.xghStorehouseId) {
        return this.$message.warning('请先选择仓库！')
      }
      let params = {
        goodsId: goods.goodsId,
        goodsIndex: index,
        storehouseId: goods.xghStorehouseId,
        accessType: this.accessType,
        billDisabled: this.billDisabled,
        id: goods.id,
        specialList: goods.attributeOrderInfoRequest
      }
      this.$refs.dialogSpecialColorSize.showDialog(params)
    },
    updateSpecialColorSize(data) {
      // console.log(data)
      let list = data.list
      let colorList = []
      for (let index = 0; index < list.length; index++) {
        let element = list[index];
        let sizeList = element.sizeList
          for (let i = 0; i < sizeList.length; i++) {
            let sizeElement = sizeList[i];
            // 如果sizeElement.id不存在，则表示是新增的规格，否则是修改的规格，为0也要传
            if (sizeElement.number > 0 || sizeElement.id) {
              colorList.push({
                goodsId: data.goodsId,
                colorId: element.colorId,
                sizeId: sizeElement.sizeId,
                number: sizeElement.number || 0,
                id: sizeElement.id
              })
            }
          }
      }
      this.TableConfig.tableData[data.goodsIndex].number = data.totalNumber
      this.TableConfig.tableData[data.goodsIndex].numberShow = formatNumber(data.totalNumber)
      this.TableConfig.tableData[data.goodsIndex].attributeOrderInfoRequest = colorList
      this.handleNumber(data.goodsIndex)
    },
    onSpecialClose() {
      console.log('onSpecialClose')
      for (let index = 0; index < this.TableConfig.tableData.length; index++) {
        let element = this.TableConfig.tableData[index];
        if (!element.showSpeial && element.goodsId) {
          element.showSpeial = true
          this.onShowSpecialColorSize(index)
          return
        }
      }
    },
    handleVisibleChange(visible) {
      console.log(visible)
      this.scrollLock = visible
    },
    // 保存表头
    onSaveExtend(item) {
      item.editHeader = false
      this.$emit('onUpdateColumn')
    },
    // 新增公式名称
    onAddFormula(item) {
      console.log(item)
      let goodsId = item.goodsId
      if (goodsId) {
        this.$refs.formula.showAddName(goodsId)
      } else {
        this.$message.warning('请先选择商品!')
      }
    },
    //公式设置
    onSetFormula(item) {
      console.log(item)

      if (!item.goodsId) {
        this.$message.warning('请先选择商品!')
      } else if (!item.formulaId) {
        this.$message.warning('请先选择计算公式!')
      } else {
        let list = item.formulaList || []
        let ac = list.find((ele) => ele.id == item.formulaId)
        this.$refs.formula.showSet(ac, this.TableConfig.columnData)
      }
    },
    formulaChange(value, item, index) {
      this.updateResultByFormula(index)

      let list = item.formulaList || []
      let ac = list.find((ele) => ele.id == value)
      if (!ac || !ac.formulaJson) {
        this.TableConfig.tableData[index].formula = ''
      } else {
        //按最新的表头名称拼接公式
        let sourceList = [
          { text: '数量', props: 'number' },
          { text: '单价', props: 'salePrice' },
          { text: '折扣单价', props: 'discountUnitPrice' },
          { text: '折扣率', props: 'discountRate' },
          { text: '税率', props: 'taxRate' },
          { text: '税额', props: 'taxPrice' },
          { text: '金额', props: 'allPrice' },
          { text: '规格', props: 'norms' },
        ]

        let columns = this.TableConfig.columnData
        for (let index = 1; index < 6; index++) {
          let key = 'extendField' + index
          let column = columns[key]
          if (column) {
            let name = column.zidingyiName || column.morenName
            sourceList.push({
              text: name,
              props: column.props,
            })
          }
        }
        for (let index = 1; index < 6; index++) {
          let key = 'extendValue' + index
          let column = columns[key]
          if (column) {
            let name = column.zidingyiName || column.morenName
            sourceList.push({
              text: name,
              props: column.props,
            })
          }
        }
        let json = JSON.parse(ac.formulaJson)
        this.TableConfig.tableData[index].formula = json
          .map((fItem) => {
            let ad = sourceList.find((sItem) => sItem.props == fItem.props)
            return ad ? ad.text : fItem.text
          })
          .join('')
      }
    },
    updateFormula(goodsId) {
      console.log(goodsId)
      getAction('/xghGoods/xghGoods/getInventoryByGoodId', { goodsId }).then((res) => {
        this.tableDataLoading = false
        if (res.code === 200) {
          let fl = res.result.formulaList || []

          //公式更新后，同步更新商品里的公式列表
          for (let index = 0; index < this.TableConfig.tableData.length; index++) {
            let element = this.TableConfig.tableData[index]
            if (element.goodsId == goodsId) {
              element.formulaList = fl
              // 更新当前所选公式对应的值
              if (element.formulaId) {
                this.formulaChange(element.formulaId, element, index)
              }
            }
          }
        }
      })
    },
    updateResultByFormula(index) {
      let goods = this.TableConfig.tableData[index]
      goods.extendValue1 = ''
      goods.extendValue2 = ''
      goods.extendValue3 = ''
      goods.extendValue4 = ''
      goods.extendValue5 = ''

      if (!goods.formulaId) {
        return
      }
      let cloneGoods = JSON.parse(JSON.stringify(goods))
      let formulaContent = goods.formulaList || []
      let ac = formulaContent.find((ele) => ele.id == goods.formulaId)
      if (ac && ac.formulaJson) {
        let list = JSON.parse(ac.formulaJson)
        let formula = list
          .map((item) => {
            return item.props
          })
          .join('')

        let equalIndex = list.findIndex((x) => x.props == '=')
        //有等号，并且在倒数第二位置，并且
        if (equalIndex != -1 && list.length > 2 && equalIndex == list.length - 2) {
          let nl = formula.split('=')[0]

          const REG = /[()+\-/\*\^ ]/g
          const params1 = nl
            .split(REG)
            .filter(Boolean)
            .filter((item) => !isNaN(item))
          const params2 = Array.from(new Set(params1)).sort((a, b) => b - a)

          let replacementMap = {}
          //替换公式内的数字，并在商品信息中设置对应key和value
          for (let i = 0; i < params2.length; i++) {
            let key = this.getKey(i)
            const val = params2[i]
            cloneGoods[key] = val
            replacementMap[val] = key
          }

          // 使用正则表达式和替换函数来替换公式中的数字
          let replacedFormula = nl.replace(/\b(\d+\.\d+|\d+)\b/g, (match) => {
            // \b 表示单词边界，确保匹配的数字是独立的
            return replacementMap[match] || match // 如果没有找到映射，则返回原始匹配（这里其实不会返回，因为所有数字都被映射了）
          })

          let result = this.calFormula(replacedFormula, cloneGoods)
          goods[formula.split('=')[1]] = result
        }
      }
    },

    //公式计算 start
    getKey(index) {
      let result = 'temp'
      for (let i = 0; i < index; i++) {
        result = result + 'p'
      }
      return result
    },
    calFormula(formula, params) {
      const tokenList = this.toPostfix(formula)
      const numarr = []
      for (const token of tokenList) {
        if (this.isOperator(token)) {
          const num2 = numarr.pop()
          const num1 = numarr.pop()
          const res = this.calculator(num1, num2, token)
          numarr.push(res)
        } else {
          numarr.push(params[token])
        }
      }
      return numarr[0]
    },
    toPostfix(formula) {
      const operatorRank = {
        '(': 0,
        ')': 0,
        '+': 1,
        '-': 1,
        '*': 2,
        '/': 2,
        '^': 3,
      }
      const tokenList = this.formulaToToken(formula)

      const result = []
      const operatorStack = []
      for (const token of tokenList) {
        // 如果是运算符
        if (this.isOperator(token)) {
          while (
            operatorStack.length > 0 &&
            operatorRank[token] <= operatorRank[operatorStack[operatorStack.length - 1]]
          ) {
            const operator = operatorStack.pop()
            result.push(operator)
          }
          operatorStack.push(token)
        } else if (token === '(') {
          operatorStack.push(token)
        } else if (token === ')') {
          while (operatorStack[operatorStack.length - 1] !== '(') {
            const operator = operatorStack.pop()
            result.push(operator)
          }
          operatorStack.pop()
        } else {
          result.push(token)
        }
      }
      while (operatorStack.length > 0) {
        result.push(operatorStack.pop())
      }
      return result
    },
    // 公式字符串转换成token数组（中缀表达式）
    formulaToToken(formula) {
      // 匹配运算符和空格
      const REG = /[()+\-/\*\^ ]/g
      const params = formula.split(REG).filter(Boolean)

      const tokens = []
      let tmpStr = formula.replace(/\s/g, '')
      while (tmpStr.length > 0) {
        if (tmpStr.startsWith(params[0])) {
          tmpStr = tmpStr.replace(params[0], '')
          tokens.push(params.shift())
        } else {
          tokens.push(tmpStr[0])
          tmpStr = tmpStr.substring(1)
        }
      }
      return tokens
    },
    // 是否是运算符
    isOperator(str) {
      const operatorReg = /[+\-/\*\^]/
      return operatorReg.test(str)
    },
    // 运算符到实际操作映射
    calculator(num1, num2, operator) {
      // console.log('----------');
      // console.log(operator);
      // console.log(num1);
      // console.log(num2);

      if (isNaN(num1)) num1 = 0
      if (isNaN(num2)) num2 = 0

      const calculators = {
        '+': (num1, num2) => accAdd(Number(num1), Number(num2)),
        '-': (num1, num2) => accSub(Number(num1), Number(num2)),
        '*': (num1, num2) => Number(num1) * Number(num2),
        '/': (num1, num2) => Number(num1) / Number(num2),
        '^': (num1, num2) => Math.pow(Number(num1), Number(num2)),
      }
      return calculators[operator](num1, num2)
    },

    //公式计算 end

    handleDeliverGoodsNumber() {
      // 如果单据是禁用状态，则不填充到整列
      if (this.billDisabled) {
        return
      }
      // 填充到整列
      this.TableConfig.tableData.forEach((item) => {
        console.log(item)
        item.deliverNum = item.numberShow
      })
    },
    updateTaxRate(val) {
      this.TableConfig.tableData.forEach((item, index) => {
        item.taxRate = val
        if (item.goodsId) {
          this.handlePrice(index)
        }
      })
    },
    updatePrice() {
      this.TableConfig.tableData.forEach((item, index) => {
        if (item.goodsId) {
          this.handlePrice(index)
        }
      })
    },
    addDragColumnWidth() {
      let that = this
      const resizers = document.querySelectorAll('.resizer')

      const setCellWidth = (cell, width) => {
        let props = cell.id
        // console.log(width);
        for (const key in that.TableConfig.columnData) {
          if (key == props) {
            let element = that.TableConfig.columnData[key]
            element.cellWidth = `${width}px`
          }
        }
      }

      resizers.forEach(function (resizer) {
        let startX
        let startWidth
        let th

        resizer.addEventListener('mousedown', function (e) {
          th = e.target.parentElement
          startX = e.clientX
          startWidth = th.offsetWidth
          document.documentElement.addEventListener('mousemove', mouseMoveHandler, false)
          document.documentElement.addEventListener('mouseup', mouseUpHandler, false)
        })

        const mouseMoveHandler = function (e) {
          const width = startWidth + (e.clientX - startX)
          setCellWidth(th, width)
        }

        const mouseUpHandler = function () {
          document.documentElement.removeEventListener('mousemove', mouseMoveHandler, false)
          document.documentElement.removeEventListener('mouseup', mouseUpHandler, false)
          that.$emit('onHandleDrag', that.TableConfig.columnData)
        }
      })
    },
    addDragColumnWidthMore() {
      let that = this
      const resizers = document.querySelectorAll('.resizer')
      let columns = JSON.parse(JSON.stringify(that.TableConfig.columnData))

      const setCellWidth = (cell, width) => {
        let props = cell.id
        for (const key in columns) {
          if (key == props) {
            let element = columns[key]
            element.cellWidth = `${width}px`
          }
        }
        console.log(that.tableId)
        if (that.tableId == 'in') {
          that.$emit('onHandleDragIn', columns)
        } else {
          that.$emit('onHandleDrag', columns)
        }
      }

      resizers.forEach(function (resizer) {
        let startX
        let startWidth
        let th

        resizer.addEventListener('mousedown', function (e) {
          th = e.target.parentElement
          startX = e.clientX
          startWidth = th.offsetWidth
          document.documentElement.addEventListener('mousemove', mouseMoveHandler, false)
          document.documentElement.addEventListener('mouseup', mouseUpHandler, false)
        })

        const mouseMoveHandler = function (e) {
          const width = startWidth + (e.clientX - startX)
          setCellWidth(th, width)
        }

        const mouseUpHandler = function () {
          document.documentElement.removeEventListener('mousemove', mouseMoveHandler, false)
          document.documentElement.removeEventListener('mouseup', mouseUpHandler, false)
          if (that.tableId == 'in') {
            that.$emit('onHandleDragIn', columns)
          } else {
            that.$emit('onHandleDrag', columns)
          }
        }
      })
    },
    // 控制输入不能超过限制位数
    inputMoney(key, val) {
      //首位不能输入"."
      val[key] = val[key].replace(/^\./g, '0.')
      val[key] = val[key].replace(/\.{2,}/g, '.') //只保留第一个. 清除多余的
      val[key] = val[key].replace('.', '$#$').replace(/\./g, '').replace('$#$', '.')
      if (this.moneyLength === 2) {
        // 小数点后面保留2位
        val[key] = val[key].replace(/^(\-)*(\d+)\.(\d\d).*$/, '$1$2.$3')
      } else {
        // 小数点后面保留4位
        val[key] = val[key].replace(/^(\-)*(\d+)\.(\d\d\d\d).*$/, '$1$2.$3')
      }
    },
    // 控制输入不能超过限制位数
    inputPrice(key, val) {
      //首位不能输入"."
      val[key] = val[key].replace(/^\./g, '0.')
      val[key] = val[key].replace(/\.{2,}/g, '.') //只保留第一个. 清除多余的
      val[key] = val[key].replace('.', '$#$').replace(/\./g, '').replace('$#$', '.')
      if (this.priceLength === 2) {
        // 小数点后面保留2位
        val[key] = val[key].replace(/^(\-)*(\d+)\.(\d\d).*$/, '$1$2.$3')
      } else {
        // 小数点后面保留4位
        val[key] = val[key].replace(/^(\-)*(\d+)\.(\d\d\d\d).*$/, '$1$2.$3')
      }
    },
    // 控制输入不能超过限制位数
    inputNumber(key, val) {
      //首位不能输入"."
      val[key] = val[key].replace(/^\./g, '0.')
      val[key] = val[key].replace(/\.{2,}/g, '.') //只保留第一个. 清除多余的
      val[key] = val[key].replace('.', '$#$').replace(/\./g, '').replace('$#$', '.')
      if (this.numLength === 2) {
        // 小数点后面保留2位
        val[key] = val[key].replace(/^(\-)*(\d+)\.(\d\d).*$/, '$1$2.$3')
      } else {
        // 小数点后面保留4位
        val[key] = val[key].replace(/^(\-)*(\d+)\.(\d\d\d\d).*$/, '$1$2.$3')
      }
    },
    async getManyNormsById(item) {
      if (!item.goodsId) return
      var res = await getAction('/xghGoods/xghGoods/getManyNormsById', {
        goodsId: item.goodsId,
      })
      if (res.code == 200) {
        item.unitList = res.result
      }
    },
    dwChange(value, item, index) {
      this.TableConfig.tableData[index].priceList = []
      this.TableConfig.tableData[index].discountList = []
      this.$emit('onHandleUnit', item, index, true)
    },
    getSubData() {
      // this.getSpStorage() // 初始化默认获取缓存中存储的曾经点击过的商品数据
      this.handleTableData() //初始化通过我们设置的this.TableConfig.columnData 表头的数据，给this.TableConfig.tableData表格新增一条空数据。
      // this.getTipTableIndex() // 初始化动态获取提示框表格在哪一列展示
      // 获取价格、金额、数量小数点位数
      let unititem = this.$lcStorage.get('toFixedList')
      if (unititem) {
        this.priceLength = unititem.unitPrice
        this.moneyLength = unititem.allPrice
        this.numLength = unititem.number
      }
    },
    // 初始化默认获取缓存中存储的曾经点击过的商品数据
    getSpStorage() {
      // 判断缓存中是否存储过商品 如果有
      if (this.$lcStorage.get('spHistoricalRecords')) {
        // 然后取出缓存中的商品数据赋值给数组并展示到页面
        this.tipSpList.listData = this.$lcStorage.get('spHistoricalRecords')
      }
    },
    /**
     * 初始化通过我们设置的this.TableConfig.columnData 表头的数据，给this.TableConfig.tableData表格新增一条空数据。
     */
    handleTableData() {
      // 初始化删除父组件传递到子组件数据时，需要隐藏的列
      let obj = {
        visible: false,
        dvisible: false,
      }
      for (const key in this.TableConfig.columnData) {
        if (key == 'discountRate') {
          obj[key] = 100
        } else if (key == 'taxRate') {
          obj[key] = 0
        } else if (key == 'taxPrice') {
          obj[key] = 0
        } else if (key !== 'idx') {
          obj[key] = ''
        }
      }
      console.log('设置了初始值', this.TableConfig.columnData, obj)
      this.tableIndex = 0
      this.TableConfig.tableData = [obj]
      for (const key in this.TableConfig.tableData[0]) {
        if (key == 'xghStorehouseId') {
          obj[key] = this.storehouseId
        }
      }
    },
    /**
     * 初始化动态获取提示框表格在哪一列展示
     */
    getTipTableIndex() {
      let arr = []
      for (const key in this.TableConfig.columnData) {
        if (this.TableConfig.columnData[key].isShow) {
          arr.push(this.TableConfig.columnData[key])
        }
      }
      arr.forEach((item, index) => {
        if (item.showType === 'table') {
          this.tipTbaleIndex = index
        }
      })
    },
    setSalePrice(item, k, value, index) {
      item[k] = value
      item.visible = false
      this.handlePriceBlur(index)
      this.handlePrice(index)
    },
    setDiscountRate(item, k, value, index) {
      if (value * 1 == 0) {
        item.dvisible = false
        this.$elMessage.warning('没有折扣信息不能选择！')
        return
      }
      item[k] = value
      item.dvisible = false
      this.handleDiscountRate(index)
    },
    // 价格输入框聚焦时
    focusPrice(e, index, confirm, transmit) {
      if (e) e.target.select()
      if (!this.PriceTracking) {
        return
      }
      let accountBook = Vue.ls.get(ACCOUNT_BOOK)
      let accountBookId = accountBook && accountBook.id
      // console.log(this.TableConfig.tableData[index])
      // 判断如果当前行选择了商品
      if (this.TableConfig.tableData[index].goodsId && !this.TableConfig.tableData[index].isGive) {
        let pl = this.TableConfig.tableData[index].priceList
        if (pl && pl.length > 0) {
          this.tipPriceList.listData = pl
          this.tipPriceList.inputName = 'salePrice'
          if (confirm) {
            let val = this.getLatestPrice(index)
            this.setSalePrice(confirm, 'salePriceShow', val, index)
          } else {
            if (this.tipPriceList.listData.length > 0) {
              this.TableConfig.tableData[index].visible = true
            }
          }
          this.$forceUpdate()
          return
        }

        //选择商品时不传递单位，后端获取最近的成交单位。 切换单位时正常传递
        let unit = transmit ? this.TableConfig.tableData[index].unit : ''
        let unitRate = transmit ? this.TableConfig.tableData[index].unitScale : ''

        // 再判断当前是销售模块还是采购模块引用了当前的组件
        if (this.orderName === 'salesBill') {
          let obj = {
            configType: '1',
            xghAccountBookId: accountBookId,
            xghCompanyId: this.companyId,
            xghGoodsId: this.TableConfig.tableData[index].goodsId,
            xghStorehouseId: this.TableConfig.tableData[index].xghStorehouseId,
            unit,
            unitRate,
          }

          postAction('/xghPriorityConfig/xghPriorityConfig/queryPriorityConfVal', obj).then((res) => {
            if (res.code === 200) {
              // 赋值给价格列表提示框
              let result = res.result || {}
              this.tipPriceList.listData = (result.xghPriorityConfigVal || []).filter((item) => {
                return (item.val && item.val != 0) || (item.valAuxiliary && item.valAuxiliary != 0)
              })
              if (transmit) {
                this.TableConfig.tableData[index].priceList = this.tipPriceList.listData
              }
              this.tipPriceList.inputName = 'salePrice'
              if (confirm) {
                let val = this.getLatestPrice(index, transmit)
                this.setSalePrice(confirm, 'salePriceShow', val, index)
              } else {
                if (this.tipPriceList.listData.length > 0) {
                  this.TableConfig.tableData[index].visible = true
                }
              }
            }
          })
        } else if (this.orderName === 'purchaseBill') {
          let obj = {
            configType: '2',
            xghAccountBookId: accountBookId,
            xghCompanyId: this.companyId,
            xghGoodsId: this.TableConfig.tableData[index].goodsId,
            xghStorehouseId: this.TableConfig.tableData[index].xghStorehouseId,
            unit,
            unitRate,
          }
          postAction('/xghPriorityConfig/xghPriorityConfig/queryPriorityConfVal', obj).then((res) => {
            if (res.code === 200) {
              // 赋值给价格列表提示框
              let result = res.result || {}
              this.tipPriceList.listData = (result.xghPriorityConfigVal || []).filter((item) => {
                return (item.val && item.val != 0) || (item.valAuxiliary && item.valAuxiliary != 0)
              })
              if (transmit) {
                this.TableConfig.tableData[index].priceList = this.tipPriceList.listData
              }
              this.tipPriceList.inputName = 'salePrice'

              if (confirm) {
                let val = this.getLatestPrice(index, transmit)
                this.setSalePrice(confirm, 'salePriceShow', val, index)
              } else {
                if (this.tipPriceList.listData.length > 0) {
                  this.TableConfig.tableData[index].visible = true
                }
              }
            }
          })
        }
        this.$forceUpdate()
      }
    },
    //获取最近的成交单位和价格
    getLatestPrice(index, transmit) {
      let list = this.tipPriceList.listData || []
      if (list.length > 0) {
        let first = list[0]
        if (first.val != first.valAuxuliary && first.unitAuxiliary && !transmit) {
          let goods = this.TableConfig.tableData[index]
          console.log(goods)
          let ul = goods.unitList || []
          let res = ul.find((item) => item.unit == first.unitAuxiliary)
          goods.unit = res.unit
          goods.unitScale = res.scale
          return first.valAuxiliary || 0
        } else {
          return first.val || 0
        }
      }
      return 0
    },
    // 折扣率输入框聚焦时
    async focusDiscountRate(e, index) {
      e.target.select()
      if (!this.discountTracking) {
        return
      }
      let accountBook = Vue.ls.get(ACCOUNT_BOOK)
      let accountBookId = accountBook && accountBook.id
      if (this.TableConfig.tableData[index].goodsId) {
        let dl = this.TableConfig.tableData[index].discountList
        if (dl && dl.length > 0) {
          this.tipPriceList.listData = dl
          this.tipDiscountList.inputName = 'discountRate'
          this.TableConfig.tableData[index].dvisible = true
          this.$forceUpdate()
          return
        }

        if (this.orderName === 'salesBill') {
          let obj = {
            configType: '3',
            xghAccountBookId: accountBookId,
            xghCompanyId: this.companyId,
            xghGoodsId: this.TableConfig.tableData[index].goodsId,
            xghStorehouseId: this.TableConfig.tableData[index].xghStorehouseId,
            unit: this.TableConfig.tableData[index].unit,
          }
          const res = await postAction('/xghPriorityConfig/xghPriorityConfig/queryPriorityConfVal', obj)
          if (res.code === 200) {
            // 赋值给价格列表提示框
            let result = res.result
            this.tipDiscountList.listData = (result.xghPriorityConfigVal || []).filter((item) => {
              return item.val && item.val != 0
            })
            this.TableConfig.tableData[index].discountList = this.tipDiscountList.listData
            this.tipDiscountList.inputName = 'discountRate'
            if (this.tipDiscountList.listData.length > 0) {
              this.TableConfig.tableData[index].dvisible = true
            }
          }
        } else if (this.orderName === 'purchaseBill') {
          let obj = {
            configType: '4',
            xghAccountBookId: accountBookId,
            xghCompanyId: this.companyId,
            xghGoodsId: this.TableConfig.tableData[index].goodsId,
            xghStorehouseId: this.TableConfig.tableData[index].xghStorehouseId,
            unit: this.TableConfig.tableData[index].unit,
          }
          const res = await postAction('/xghPriorityConfig/xghPriorityConfig/queryPriorityConfVal', obj)
          if (res.code === 200) {
            // 赋值给价格列表提示框
            let result = res.result
            this.tipDiscountList.listData = (result.xghPriorityConfigVal || []).filter((item) => {
              return item.val && item.val != 0
            })
            this.TableConfig.tableData[index].discountList = this.tipDiscountList.listData
            this.tipDiscountList.inputName = 'discountRate'
            if (this.tipDiscountList.listData.length > 0) {
              this.TableConfig.tableData[index].dvisible = true
            }
          }
        }
        this.$forceUpdate()
      }
    },
    focusSelect(e) {
      e.target.select()
      console.log(e)
    },
    changeCK(value, item, index) {
      console.log(item)

      // 出库状态 + 不允许负库存 = 查询当前仓库仓前商品可用数量，并更新数量
      if (this.accessType == 'out' && !this.allowNegative && item.goodsId) {
        if (item.specialColorSize && item.number > 0) {
          //特殊商品
          item.showSpeial = false
          this.onSpecialClose()
        } else {
          //正常商品
          let params = {
            goodsId: item.goodsId,
            storehouseId: item.xghStorehouseId,
          }
          getAction('/xghStorehouseGoods/xghStorehouseGoods/getNumberByGoodsIdAndStorehouseId', params).then((res) => {
            console.log(res)
            if (res.success) {
              let nUse = res.result.number //不再使用可用数量20250110
              item.useNumber = nUse
              this.handleNumber(index)
            } else {
              this.$elMessage.error(res.message)
            }
          })
        }
      }
    },
    // 数量改变
    handleNumber(index) {
      const tableData = this.TableConfig.tableData[index]
      this.TableConfig.tableData[index].number = formatFour(Math.abs(tableData.numberShow))
      this.TableConfig.tableData[index].numberShow = formatNumber(Math.abs(tableData.numberShow))
      if (this.billName == '销售订单') {
        this.TableConfig.tableData[index].notDeliverNumber = this.TableConfig.tableData[index].number
        this.TableConfig.tableData[index].notDeliverNumberShow = this.TableConfig.tableData[index].numberShow
      }
      if (this.TableConfig.tableData[index].goodsId) {
        if (this.accessType == 'out') {
          let item = this.TableConfig.tableData[index]
          let number = Number(item.number)
          let useNumber = Number(item.useNumber)
          // 非必用版才验证库存
          if (!this.isBaseVersion && number > useNumber && !this.allowNegative) {
            this.$elMessage.warning('输入数量已超出库存数量，已重置为最大库存数量')
            let max = Math.max(0, useNumber)
            item.number = formatFour(max)
            item.numberShow = formatNumber(max)
          }
        }

        // 税额 = 折扣单价 * 税率 / 100
        this.taxPriceFun(index)
        // 如果当前勾选了赠品
        this.allPriceFun(index)

        if (this.orderName === 'salesBill' && this.billName == '销售订单') {
          this.TableConfig.tableData[index].notDeliverNumber = this.TableConfig.tableData[index].number
        } else if (this.orderName === 'purchaseBill' && this.billName == '采购订单') {
          this.TableConfig.tableData[index].notArrivalNumber = this.TableConfig.tableData[index].number
          this.TableConfig.tableData[index].notArrivalNumberShow = formatNumber(
            this.TableConfig.tableData[index].number
          )
        }
      }
      this.updateResultByFormula(index)
    },
    handleDeliverGoodsNumberBlur(index) {
      const tableData = this.TableConfig.tableData[index]
      console.log(tableData, '====tableData')
      const currentNumber = Number(tableData.numberShow)

      // 格式化输入的送货数量
      this.TableConfig.tableData[index].deliverNum = formatNumber(Math.abs(tableData.deliverNum))
      // 检查送货数量是否超过当前行的数量
      let deliverNumber = Number(this.TableConfig.tableData[index].deliverNum)
      if (deliverNumber > currentNumber) {
        this.$elMessage.warning('送货数量不能超过当前货物的数量，已重置为当前货物的最大数量')
        deliverNumber = currentNumber
        this.TableConfig.tableData[index].deliverNum = formatNumber(deliverNumber)
        // this.TableConfig.tableData[index].deliverGoodsNumberShow = formatNumber(deliverNumber)
      }
    },
    // 销售单价/采购单价改变
    handlePrice(index) {
      // console.log('销售单价/采购单价改变')
      if (this.TableConfig.tableData[index].hasOwnProperty('visible')) {
        this.TableConfig.tableData[index].visible = false
      }
      if (this.TableConfig.tableData[index].goodsId) {
        // 折扣单价 =（销售单价*折扣率）/ 100
        this.discountUnitPriceFun(index)
        // 含税单价 = 折扣单价 + 折扣单价*税率/100
        this.taxUnitPriceFun(index)
        // 税额 = 折扣单价 * 税率 / 100
        this.taxPriceFun(index)
        // 如果当前勾选了赠品
        this.allPriceFun(index)

        setTimeout(() => {
          this.updateResultByFormula(index)
        }, 200)
      }
    },
    handlePriceBlur(index) {
      const item = this.TableConfig.tableData[index]

      let price = Math.abs(delcommafy(item.salePriceShow))
      this.TableConfig.tableData[index].salePrice = price
      this.TableConfig.tableData[index].salePriceShow = formatPrice(price)
      this.handlePrice(index)
    },
    // 折扣率改变
    handleDiscountRate(index) {
      this.TableConfig.tableData[index].dvisible = false
      this.TableConfig.tableData[index].discountRate = Math.abs(this.TableConfig.tableData[index].discountRate)
      if (this.TableConfig.tableData[index].discountRate > 100) {
        this.TableConfig.tableData[index].discountRate = 100
      }
      if (this.TableConfig.tableData[index].goodsId) {
        // 折扣单价 =（销售单价*折扣率）/ 100
        this.discountUnitPriceFun(index)

        // 含税单价 = 折扣单价 + 折扣单价*税率/100
        this.taxUnitPriceFun(index)

        // 税额 = 折扣单价 * 税率 / 100
        this.taxPriceFun(index)

        // 如果当前勾选了赠品
        this.allPriceFun(index)
      }
    },
    handleDiscountBlur(index) {
      this.handleDiscountRate(index)
    },
    // 折扣单价改变
    handleDiscountUnitPrice(index) {
      if (this.TableConfig.tableData[index].goodsId) {
        // 销售单价 = 折扣单价 / (折扣率/100)
        this.salePriceFun(index)

        // 含税单价 = 折扣单价 + 折扣单价*税率/100
        this.taxUnitPriceFun(index)

        // 税额 = 折扣单价 * 税率 / 100
        this.taxPriceFun(index)

        // 如果当前勾选了赠品
        this.allPriceFun(index)
      }
    },
    // 税率改变
    handleTaxRate(index) {
      this.TableConfig.tableData[index].taxRate = Math.abs(this.TableConfig.tableData[index].taxRate)
      if (this.TableConfig.tableData[index].goodsId) {
        // 含税单价 = 折扣单价 + 折扣单价*税率/100
        this.taxUnitPriceFun(index)

        // 税额 = 折扣单价 * 税率 / 100
        this.taxPriceFun(index)

        // 如果当前勾选了赠品
        this.allPriceFun(index)
      }
    },
    // 含税单价改变
    handleTaxUnitPrice(index) {
      this.TableConfig.tableData[index].taxUnitPrice = Math.abs(
        delcommafy(this.TableConfig.tableData[index].taxUnitPriceShow)
      )
      this.TableConfig.tableData[index].taxUnitPriceShow = formatPrice(this.TableConfig.tableData[index].taxUnitPrice)
      if (this.TableConfig.tableData[index].goodsId) {
        // 折扣单价 = 含税单价/(1+税率/100)
        this.unDiscountUnitPriceFun(index)

        // 销售单价 = 折扣单价 / (折扣率/100)
        this.salePriceFun(index)

        // 税额 = 折扣单价 * 税率 / 100
        this.taxPriceFun(index)

        // 如果当前勾选了赠品
        this.allPriceFun(index)
      }
    },
    // 商品条形码改变
    handleGoodsCode(index) {
      // 判断是否启用了价格跟踪或折扣率跟踪，且页面上有往来单位的，需要提示，库存调整单不需要提示
      if ((this.PriceTracking || this.discountTracking) && !this.companyId && this.orderName != '库存调整单') {
        this.$elMessage({
          showClose: true,
          message: `价格跟踪或折扣跟踪模式下请先选择${this.orderName == 'purchaseBill' ? '供应商' : '客户'}！`,
          type: 'error',
          iconClass: 'el-icon-warning-outline',
          duration: 3000,
        })
        return
      } else if (this.accessType == 'out' && !this.storehouseId) {
        this.$elMessage.warning('出库状态下请先选择出库仓库')
        return
      }
      let goodsCode = this.TableConfig.tableData[index].goodsCode
      let storehouseId = this.TableConfig.tableData[index].xghStorehouseId || this.storehouseId
      if (goodsCode) {
        getAction('/xghGoods/xghGoods/queryByBarCode', { barCode: goodsCode, storehouseId }).then((res) => {
          console.log(res)
          if (res.success) {
            let result = res.result
            if (typeof result == 'string') {
              this.$elMessage.error(result)
              this.TableConfig.tableData[index].goodsCode = ''
            } else {
              this.tableIndex = index
              this.onSelectCommodity(result)
            }
          } else {
            this.$elMessage.error(res.message)
          }
        })
      }
    },
    // 金额改变
    handleAllPrice(index) {
      this.TableConfig.tableData[index].allPrice = Math.abs(delcommafy(this.TableConfig.tableData[index].allPriceShow))
      this.TableConfig.tableData[index].allPriceShow = formatMoney(this.TableConfig.tableData[index].allPrice)
      if (this.TableConfig.tableData[index].goodsId) {
        // 如果当前勾选了赠品
        if (this.TableConfig.tableData[index].isGive) {
          // 金额 = 0
          this.TableConfig.tableData[index].allPrice = formatFour(0)
          this.TableConfig.tableData[index].allPriceShow = formatMoney(0)
        } else {
          if (this.TableConfig.tableData[index].number) {
            // 含税单价 = 金额/数量
            let taxUnitPrice =
              delcommafy(this.TableConfig.tableData[index].allPrice || 0) /
              Number(this.TableConfig.tableData[index].number || 0)

            this.TableConfig.tableData[index].taxUnitPrice = delcommafy(taxUnitPrice)
            this.TableConfig.tableData[index].taxUnitPriceShow = formatMoney(taxUnitPrice)
            // 折扣单价 = 含税单价/(1+税率/100)
            this.unDiscountUnitPriceFun(index)
            // 销售单价 = 折扣单价 / (折扣率/100)
            this.salePriceFun(index)
            this.taxPriceFun(index)
          } else {
            this.$elMessage({
              showClose: true,
              message: '请先输入价格！',
              type: 'error',
              iconClass: 'el-icon-warning-outline',
              duration: 3000,
            })
            this.TableConfig.tableData[index].allPrice = 0
          }
        }
      }
    },
    // 税额
    taxPriceFun(index) {
      // 税额=折扣单价*税率
      let item = this.TableConfig.tableData[index]

      let taxPrice =
        (delcommafy(item.discountUnitPrice || 0) * Number(item.taxRate || 0) * Number(item.number || 0)) / 100
      this.TableConfig.tableData[index].taxPrice = delcommafy(taxPrice)
      this.TableConfig.tableData[index].taxPriceShow = formatMoney(taxPrice)
    },
    // 金额
    allPriceFun(index) {
      // 如果当前勾选了赠品
      if (this.TableConfig.tableData[index].isGive) {
        this.TableConfig.tableData[index].allPrice = delcommafy(0)
        this.TableConfig.tableData[index].allPriceShow = formatMoney(0)
      } else {
        // 金额 = 含税单价 * 数量
        let tup = this.TableConfig.tableData[index].taxUnitPrice
        let n = this.TableConfig.tableData[index].number
        let allPrice = accMul(delcommafy(tup), delcommafy(n))
        this.TableConfig.tableData[index].allPrice = delcommafy(allPrice)

       let tups = this.TableConfig.tableData[index].taxUnitPriceShow
       let ns = this.TableConfig.tableData[index].numberShow
       let allPrices = accMul(delcommafy(tups), delcommafy(ns))
       this.TableConfig.tableData[index].allPriceShow = formatMoney(allPrices)
      }
    },
    // 折扣单价
    discountUnitPriceFun(index) {
      // 折扣单价 =（销售单价*折扣率）/ 100
      let discountUnitPrice =
        accMul(
          delcommafy(this.TableConfig.tableData[index].salePriceShow),
          delcommafy(this.TableConfig.tableData[index].discountRate)
        ) / 100

      this.TableConfig.tableData[index].discountUnitPrice = delcommafy(discountUnitPrice)
      this.TableConfig.tableData[index].discountUnitPriceShow = formatPrice(discountUnitPrice)
    },
    // 倒推折扣单价
    unDiscountUnitPriceFun(index) {
      // 折扣单价 = 含税单价/(1+税率/100)
      let discountUnitPrice =
        delcommafy(this.TableConfig.tableData[index].taxUnitPriceShow || 0) /
        (1 + Number(this.TableConfig.tableData[index].taxRate || 0) / 100)
      this.TableConfig.tableData[index].discountUnitPrice = delcommafy(discountUnitPrice)
      this.TableConfig.tableData[index].discountUnitPriceShow = formatPrice(discountUnitPrice)
    },
    // 含税单价
    taxUnitPriceFun(index) {
      // 含税单价 = 折扣单价 + 折扣单价*税率/100
      let taxUnitPrice =
        delcommafy(this.TableConfig.tableData[index].discountUnitPriceShow) +
        (delcommafy(this.TableConfig.tableData[index].discountUnitPriceShow) *
          Number(this.TableConfig.tableData[index].taxRate)) /
          100
      this.TableConfig.tableData[index].taxUnitPrice = delcommafy(taxUnitPrice)
      this.TableConfig.tableData[index].taxUnitPriceShow = formatPrice(taxUnitPrice)
    },
    // 销售单价
    salePriceFun(index) {
      // if (this.orderName === 'salesBill') {
      // 销售单价 = 折扣单价 / (折扣率/100)
      let salePrice =
        delcommafy(this.TableConfig.tableData[index].discountUnitPriceShow || 0) /
        (delcommafy(this.TableConfig.tableData[index].discountRate || 0) / 100)
      this.TableConfig.tableData[index].salePrice = delcommafy(salePrice)
      this.TableConfig.tableData[index].salePriceShow = formatPrice(salePrice)
      // } else if (this.orderName === 'purchaseBill') {
      //   // 采购单价 = 折扣单价 / (折扣率/100)
      //   this.TableConfig.tableData[index].goodsPrice =
      //     Number(
      //       (
      //         Number(this.TableConfig.tableData[index].discountUnitPrice || 0) /
      //         (Number(this.TableConfig.tableData[index].discountRate || 0) / 100)
      //       ).toFixed(this.$lcStorage.get('toFixedList').number)
      //     ) || 0
      // }
    },

    /**
     * 监听判断赠品选择框是否发生改变
     * @param value 当前选择框的状态
     * @param index 当前选择行的下标
     */
    onHandleIsGive(value, index) {
      this.allPriceFun(index)
    },
    /**
     * 合计列求和
     */
    onSum() {
      // console.log('onSum', this.TableConfig.columnData)
      for (const key in this.TableConfig.columnData) {
        if (this.TableConfig.columnData[key].isSum) {
          // var sum = 0
          // for (let i = 0; i < this.TableConfig.tableData.length; i++) {
          //   sum += Number(delcommafy(this.TableConfig.tableData[i][key]))
          // }
          var sum = this.TableConfig.tableData.reduce(function (acc, obj) {
            return accAdd(acc, delcommafy(obj[key]))
          }, 0)
          // let decimalPlace = this.$lcStorage.get('toFixedList') ? this.$lcStorage.get('toFixedList').number : 2
          // this.TableConfig.columnData[key]['sumValue'] = formatMoney(sum) //Number(sum).toFixed(decimalPlace)
          if (key.toLowerCase().includes('number') || key.toLowerCase().includes('num')) {
            // 判断是数量的用formatNumber
            this.TableConfig.columnData[key]['sumValue'] = formatNumber(sum) //Number(sum).toFixed(decimalPlace)
          } else {
            // 其它默认是金额用formatMoney
            this.TableConfig.columnData[key]['sumValue'] = formatMoney(sum) //Number(sum).toFixed(decimalPlace)
          }
        }
      }
      // console.log(this.TableConfig.columnData.allPrice);
      if (this.orderName === 'salesBill') {
        this.$emit('onHandleAllPrice', this.TableConfig.columnData.allPriceShow.sumValue)
      } else if (this.orderName === 'purchaseBill') {
        this.$emit('onHandleAllPrice', this.TableConfig.columnData.allPriceShow.sumValue)
      }
    },

    // 点击显示选项仓库的提示框
    onShowCk(index) {
      let tableBox
      if (this.tableId) {
        let tableIdName = this.tableId
        tableBox = document.getElementById(tableIdName)
      } else {
        tableBox = document.getElementById('tableId')
      }
      let uls = tableBox.getElementsByClassName('select_option_ck')
      for (let i = 0; i < uls.length; i++) {
        if (i == index) {
          if (uls[i].style.display == 'flex') {
            uls[i].style.display = 'none'
          } else {
            uls[i].style.display = 'flex'
          }
        } else {
          uls[i].style.display = 'none'
        }
      }
    },
    // 选中某一行仓库
    onClickCk(v, i, index) {
      this.TableConfig.tableData[index].xghStorehouseId = v.id
      this.TableConfig.tableData[index].xghStorehouse = v.storehouseName
      this.selectLiCk = i
      let uls = document.getElementsByClassName('select_option_ck')
      for (let i = 0; i < uls.length; i++) {
        uls[i].style.display = 'none'
      }
    },
    // 点击显示选项单位的提示框
    onShowUnit(index) {
      let tableBox
      if (this.tableId) {
        let tableIdName = this.tableId
        tableBox = document.getElementById(tableIdName)
      } else {
        tableBox = document.getElementById('tableId')
      }
      let uls = tableBox.getElementsByClassName('select_option')
      for (let i = 0; i < uls.length; i++) {
        if (i == index) {
          if (uls[i].style.display == 'flex') {
            uls[i].style.display = 'none'
          } else {
            uls[i].style.display = 'flex'
          }
        } else {
          uls[i].style.display = 'none'
        }
      }
    },

    //表格宽度调整事件
    tblresize() {},
    // 打开选择商品弹出框
    onShowCommodity(index) {
      // 判断是否启用了价格跟踪或折扣率跟踪，且页面上有往来单位的，需要提示，库存调整单不需要提示
      if ((this.PriceTracking || this.discountTracking) && !this.companyId && this.orderName != '库存调整单') {
        this.$elMessage.warning(
          `价格跟踪或折扣跟踪模式下请先选择${this.orderName == 'purchaseBill' ? '供应商' : '客户'}！`
        )
      } else if (this.accessType == 'out' && !this.storehouseId) {
        this.$elMessage.warning('出库状态下请先选择出库仓库')
      } else {
        this.tableIndex = index
        this.activeStorehouseId = this.TableConfig.tableData[index].xghStorehouseId || this.storehouseId
        let goodIds = []
        if (this.TableConfig.tableData.length && !this.isInputManyGoods) {
          for (let i = 0; i < this.TableConfig.tableData.length; i++) {
            if (this.TableConfig.tableData[i].goodsId) {
              goodIds.push(this.TableConfig.tableData[i].goodsId)
            }
            // goodIds.push(this.TableConfig.tableData[i].goodsId)
          }
        }
        this.$refs.commodityRef.goodIds = goodIds
        if (this.isInputManyGoods || goodIds.length == 0) {
          this.$refs.commodityRef.multipleSelection = []
        }
        this.$refs.commodityRef.dialogVisible = true
      }
    },
    // 重置商品选择框
    onResetCommodity() {
      this.$refs.commodityRef.multipleSelection = []
    },
    // 选择商品
    onSelectCommodity(val) {
      // 判断是否允许同一商品信息录入多行
      // 如果不允许，需要校验是否重复
      if (this.TableConfig.tableData.length && !this.isInputManyGoods) {
        for (let i = 0; i < this.TableConfig.tableData.length; i++) {
          if (this.TableConfig.tableData[i].goodsId === val.id && this.tableIndex != i) {
            return
          }
        }
      }
      val.useNumber = Number(val.number) || 0
      // 价格和折扣率追踪放到单据页面中进行
      let number = this.accessType == 'out' ? Math.min(1, Math.max(val.useNumber, 0)) : 1
      if ((val.specialFunctionType || '').includes('1')) {
        number = 0
      }
      val.number = formatFour(number) //做单时数量
      val.numberShow = formatNumber(number)
      // 单价
      val.salePrice = formatFour(val.salePriceShow || 0)
      val.salePriceShow = formatPrice(val.salePriceShow || 0)

      // 在获取商品后，事件发射到父组件通知父组件来处理数据字段名不统一问题
      this.$emit('onHandleSpData', this.TableConfig.tableData, this.tableIndex, val)

      let config = sysConfig()
      if (config.skip_line_after_product_entry) {
        this.addRow(this.TableConfig.tableData, this.TableConfig.tableData.length - 1)
      }
    },
    // 多选商品弹窗
    onSelectCommodityMultiple(multipleData, goodIds) {

      //过滤新选的商品加入单据商品列表
      for (let index = 0; index < multipleData.length; index++) {
        let element = multipleData[index]
        let ac = this.TableConfig.tableData.find((item) => item.goodsId == element.id)
        if (!ac || this.isInputManyGoods) {
          //选择商品时，将数量赋值给可用数量
          this.setMultipleCommodity(element)
        }
      }
      //过滤单据商品列表中被移除的商品
      let maxIndex = this.TableConfig.tableData.length - 1
      for (let index = maxIndex; index >= 0; index--) {
        let element = this.TableConfig.tableData[index]
        let ac = multipleData.find((item) => item.id == element.goodsId)
        if (!this.isInputManyGoods && (!ac || !element.goodsId) && !goodIds.includes(element.goodsId)) {
          this.deleteRow(index)
        }
      }
      // 开启商品录入成功后立即跳行
      let config = sysConfig()
      if (config.skip_line_after_product_entry) {
        this.addRow(this.TableConfig.tableData, this.TableConfig.tableData.length - 1)
      }

      console.log(this.TableConfig.tableData)
      this.onSpecialClose()
    },
    // 处理数据添加到列表中
    setMultipleCommodity(val) {
      // 判断是否允许同一商品信息录入多行
      // 如果不允许，需要校验是否重复
      if (this.TableConfig.tableData.length && !this.isInputManyGoods) {
        for (let i = 0; i < this.TableConfig.tableData.length; i++) {
          if (this.TableConfig.tableData[i].goodsId === val.id) {
            return
          }
        }
      }
      val.useNumber = Number(val.number) || 0
      // 价格和折扣率追踪放到单据页面中进行
      let number = this.accessType == 'out' ? Math.min(1, Math.max(val.useNumber, 0)) : 1
      if ((val.specialFunctionType || '').includes('1')) {
        number = 0
        val.showSpeial = false
      } else {
        val.showSpeial = true
      }
      val.number = formatFour(number) //做单时数量
      val.numberShow = formatNumber(number)

      // 单价
      val.salePrice = formatFour(0)
      val.salePriceShow = formatPrice(0)
      this.isAddCommodity = true
      console.log(1111, this.TableConfig.tableData.length)
      // 查找空数据添加数据
      for (let i = 0; i < this.TableConfig.tableData.length; i++) {
        if (!this.TableConfig.tableData[i].goodsId) {
          return this.$emit('onHandleSpData', this.TableConfig.tableData, i, val)
        }
      }
      // 没有空行，先增加一行空数据
      this.addRow(this.TableConfig.tableData, this.TableConfig.tableData.length - 1)
      // 在获取商品后，事件发射到父组件通知父组件来处理数据字段名不统一问题
      this.$emit('onHandleSpData', this.TableConfig.tableData, this.TableConfig.tableData.length - 1, val)
    },

    // 选择仓库的商品
    onSelectWarehouseGoods(val) {
      // 判断是否允许同一商品信息录入多行
      // 如果不允许，需要校验是否重复
      if (this.TableConfig.tableData.length && !this.isInputManyGoods) {
        for (let i = 0; i < this.TableConfig.tableData.length; i++) {
          if (this.TableConfig.tableData[i].goodsId === val.id) {
            this.$elMessage({
              showClose: true,
              message: '不能重复选择商品！',
              type: 'error',
              iconClass: 'el-icon-warning-outline',
              duration: 3000,
            })
            return
          }
        }
      }
      // 价格和折扣率追踪放到单据页面中进行
      val.number = formatFour(1) //做单时数量，不能为查出来的商品数量 Number(val.number) || 0 // 数量,
      val.numberShow = formatNumber(1)
      // 单价
      val.salePrice = formatFour(0)
      val.salePriceShow = formatPrice(0)
      // 折扣率
      val.discountRate = this.discountRate
      // 折扣单价、含税单价需要重新计算
      // 折扣单价 = 单价 * 折扣率
      // val.discountUnitPrice = Number(parseFloat(val.salePrice) * parseFloat(val.discountRate)).toFixed(this.priceLength) // 折扣单价
      // val.taxRate = Number(val.taxRate) || 0 // 税率
      // 含税单价 = 折扣单价 * （1 + 税率）
      // val.taxUnitPrice = Number(parseFloat(val.discountUnitPrice) * (1 + val.taxRate / 100)).toFixed(this.priceLength) // 含税单价
      // 税额 = 折扣单价 * 税率
      // val.taxPrice = Number((parseFloat(val.discountUnitPrice) * val.taxRate) / 100).toFixed(this.moneyLength) // 税额
      val.allPrice = formatFour(0) // 金额
      val.allPriceShow = formatMoney(0)
      // 在获取商品后，事件发射到父组件通知父组件来处理数据字段名不统一问题
      this.$emit('onHandleSpData', this.TableConfig.tableData, this.tableIndex, val)

      let config = sysConfig()
      if (config.skip_line_after_product_entry) {
        this.addRow(this.TableConfig.tableData, this.tableIndex)
      }
    },
    // 获取新增商品数据
    onAddCommodity(res) {
      this.newData = this.$options.data().newData
      this.onSelectCommodity(res)
      this.$refs.commodityRef.getData()
    },
    // 关闭新增商品时清空
    onCloseAddCommodity() {
      this.newData = this.$options.data().newData
    },
    // 历史记录数据去重并只展示三个数据方法
    selectDataHas(arr) {
      let map = new Map()
      for (const item of arr) {
        if (!map.has(item.id)) {
          map.set(item.id, item)
        }
      }
      let newArr = [...map.values()]
      return newArr.slice(0, 3)
    },
    // 表格聚焦时触发
    gridOnFocus(event) {
      const inputs = this.handleInputs().inputs
      const focusedElement = event.target // 获取当前聚焦的元素
      const currentInputs = this.handleInputs().currentInputs // 获取包含行和列的元素表
      // 定位聚焦元素的行和列
      currentInputs.forEach((item) => {
        if (item.input === focusedElement) {
          ;(this.currentCol = item.column), (this.currentRow = item.row)
          return
        }
      })
      // focusedElement.select()
      // 确保聚焦的元素是输入框
      // 找到当前输入框所在的 td
      // const td = this.findtd(focusedElement) // 假设有一个方法可以找到 td
      // if (td && td.parentNode) {
      //   const tr = td.parentNode // 获取所在的 tr
      //   // 获取当前行的索引
      //   const rowIndex = Array.prototype.indexOf.call(tr.parentNode.children, tr)
      //   // 获取当前列的索引
      //   const columnIndex = Array.prototype.indexOf.call(tr.children, td)
      //   this.currentCol = columnIndex
      //   this.currentRow = rowIndex
      //   console.log(this.currentCol, this.currentRow)
      // }
      return
      // 判断当前触发的节点为输入框
      if (obj.nodeName == 'INPUT') {
        let td = this.findtd(obj) // 找到当前输入框的td
        let tr = td.parentNode // 找到当前td所在的tr
        // 得到当前页面所显示的td元素
        let trTd = tr.getElementsByClassName('tdDom')
        let myindex = Array.prototype.indexOf.call(trTd, td) // 判断当前所触发元素在当前行的第几列
        // 全局使用判断当前所触发的输入框位于表格的第几行
        this.tableIndex = Array.prototype.indexOf.call(tr.parentNode.children, tr)
        // 判断是否是需要弹出提示框的列
        if (myindex == this.tipTbaleIndex) {
          // 弹出提示框并改变提示框位置
          this.tipSpList.top = td.offsetParent.offsetTop + 34
          this.tipSpList.left = obj.offsetParent.offsetLeft
          this.tipSpList.displaySta = 'block'
          // 判断当前输入框的内的值是否与提示框内的值匹配，如果匹配提示框改为选中状态
          this.OnFocusHandle(obj)
        } else {
          this.tipSpList.displaySta = 'none'
        }
        // 判断是否需要弹出价格列表的弹出框
        if (myindex == 8 || myindex == 9) {
          // 弹出提示框并改变提示框位置
          this.tipPriceList.top = td.offsetParent.offsetTop + 34
          this.tipPriceList.left = obj.offsetParent.offsetLeft
          this.tipPriceList.displaySta = 'block'
        } else {
          this.tipPriceList.displaySta = 'none'
        }
      }
    },
    // 辅助方法：找到当前输入框所在的 td
    findtd(elm) {
      if (elm && elm.parentNode) {
        if (elm.parentNode.nodeName === 'TD') {
          return elm.parentNode
        } else {
          return this.findtd(elm.parentNode)
        }
      }
    },
    // 商品输入框聚焦时处理
    OnFocusHandle(obj) {
      for (let i = 0; i < this.tipSpList.listData.length; i++) {
        // 判断当前输入框的值与提示框的哪一行值匹配
        if (this.tipSpList.listData[i].goodsName == obj.value) {
          this.tipSpList.mark = i // 改变提示框选中行下标
          this.selecSptListData = this.tipSpList.listData[this.tipSpList.mark]
          let cptbl = document.getElementById('tipTable')
          let ptr = cptbl.rows[this.tipSpList.mark]
          // 避免第一次触发出现问题 添加定时器（由于现在商品只展示历史记录的最近三条，所以不用当前操作）
          // setTimeout(() => {
          //   // 将当前选中行滚动到浏览器可视区域
          //   ptr.scrollIntoViewIfNeeded()
          // }, 0)
          return
        } else {
          this.tipSpList.mark = -1
        }
      }
    },
    // 失焦时触发
    gridOnBlur() {
      // this.tipSpList.displaySta = 'none'
    },
    // 键盘按下时触发
    gridOnKeyDown(event) {
      let inputs = this.handleInputs().inputs
      const columnKeys = this.handleInputs().columnKeys
      if (event.key === 'ArrowRight') {
        // 如果按下右箭头，移动到下一个输入框
        this.handleArrowRight(event, inputs, columnKeys)
      } else if (event.key === 'ArrowLeft') {
        // 如果按下左箭头，移动到上一个输入框
        this.handleArrowLeft(event, inputs, columnKeys)
      } else if (event.key === 'ArrowDown') {
        // 如果按下下箭头，选择下一行
        this.handleArrowDown(event, inputs, columnKeys)
      } else if (event.key === 'ArrowUp') {
        // 如果是number类型的输入框，不做后续处理，上下键是加减数字的
        const inputToFocus1 = inputs[this.currentRow * columnKeys.length + this.currentCol]
        if (inputToFocus1 && inputToFocus1.nodeName === 'INPUT' && inputToFocus1.type == 'number') {
          return
        }
        // 如果按下上箭头，选择上一行
        if (this.currentRow > 0) {
          this.currentRow--
          const inputToFocus = inputs[this.currentRow * columnKeys.length + this.currentCol]
          this.inputDomToFocus(event, inputToFocus, inputs)
          event.preventDefault()
        }
      }
      return
      let obj = event.target // 当前触发的input
      let td = this.findtd(obj) // 当前input所在的td
      let tdRight = td.nextElementSibling // 当前td的右边
      let tdLeft = td.previousElementSibling // 当前td的左边
      let tr = td.parentNode // 当前td所在的tr
      let trUp = tr.previousElementSibling // 当前tr的上一行（此时包含被隐藏的td）
      if (trUp) {
        trUp = trUp.getElementsByClassName('tdDom') // 当前tr的上一行（此时的tr内包含的都是显示在页面上的td）
      }
      let trDown = tr.nextElementSibling // 当前tr的下一行（此时包含被隐藏的td）
      if (trDown) {
        trDown = trDown.getElementsByClassName('tdDom') // 当前tr的下一行（此时的tr内包含的都是显示在页面上的td）
      }
      // 得到当前页面所显示的td元素
      let trTd = tr.getElementsByClassName('tdDom')
      let myindex = Array.prototype.indexOf.call(trTd, td) // 判断当前所触发元素在当前行的第几列
      // 判断当前所触发的节点 位于表格的第几行 this.tableIndex
      this.getTrIndex(tr)
      // 如果触发的是输入框 且 触发的是商品名称列数据时
      // if (obj.nodeName == 'INPUT' && myindex == 3) {
      if (obj.nodeName == 'INPUT' && myindex == this.tipTbaleIndex) {
        // 如果当前键盘事件为向下 且 提示框为显示状态
        if (event.key == 'ArrowDown' && this.tipSpList.displaySta == 'block') {
          this.handleTipBox('ArrowDown')
        } else if (event.key == 'ArrowUp' && this.tipSpList.displaySta == 'block') {
          // 如果当前键盘事件为向上 且 提示框为显示状态
          this.handleTipBox('ArrowUp')
        } else if (event.key == 'Enter' && this.tipSpList.displaySta == 'block' && this.tipSpList.mark != -1) {
          // 如果当前键盘事件为回车 且 提示框为显示状态 提示框内也有选择数据时
          this.handleTipBoxEnter(tdRight, 'Enter')
        } else if (event.key == 'ArrowRight' || (event.key == 'Enter' && this.tipSpList.displaySta == 'block')) {
          // 如果当前键盘事件为回车 且 提示框为显示状态
          this.handleTipBoxEnter(tdRight)
        } else if (event.key == 'ArrowLeft') {
          // 如果当前键盘事件为向左
          this.nodeSelect(tdRight, tdLeft, tr, trUp, trDown, myindex)
        }
      } else {
        // 当触发的不是商品名称列节点时 隐藏提示框
        this.tipSpList.displaySta = 'none'
        this.tipPriceList.displaySta = 'none'
        // 判断键盘事件 选择相应的节点
        this.nodeSelect(tdRight, tdLeft, tr, trUp, trDown, myindex)
      }
    },
    // 处理inputs数据
    handleInputs() {
      // 拿到所有类为input-field的元素
      let inputs = this.$el.querySelectorAll('.input-field')
      // 去掉隐藏的tdDom元素
      inputs = Array.from(inputs).filter((input) => {
        const parent = this.findTdWithClass(input)
        return parent && (!parent.style || parent.style.display !== 'none')
      })
      // 拿到所有正常显示的列的个数
      let arr = []
      for (const key in this.TableConfig.columnData) {
        if (this.TableConfig.columnData[key].isShow && this.TableConfig.columnData[key].zidingyiState) {
          arr.push(this.TableConfig.columnData[key])
        }
      }
      const columnKeys = arr
      // 给元素添加行标和列标，聚焦时方便找到第几行第几列
      let currentInputs = []
      inputs.forEach((input, index) => {
        currentInputs.push({
          input,
          column: Math.floor(index % columnKeys.length),
          row: Math.floor(index / columnKeys.length),
        })
      })
      /**
       * inputs 是所有打了input-field类标签的元素
       * columnKeys 是所有显示出来的列，需要计算总数
       * currentInputs 是inputs的扩展，在每个对应的元素基础上，增加了所在的行和列
       */
      return { inputs, columnKeys, currentInputs }
    },
    // 递归寻找toDom元素
    findTdWithClass(inputElement) {
      let currentElement = inputElement
      // 循环向上查找父元素
      while (currentElement) {
        // 检查当前元素是否是 th 元素并且具有 toDom 类
        if (currentElement.nodeName === 'TD' && currentElement.classList.contains('tdDom')) {
          return currentElement // 找到符合条件的 th 元素，返回
        }
        currentElement = currentElement.parentElement // 移动到父元素
      }
      return null // 如果没有找到，返回 null
    },
    // 处理右键头事件
    handleArrowRight(event, inputs, columnKeys) {
      console.log(this.currentCol)
      if (this.currentCol < inputs.length - 1) {
        this.currentCol++
        const inputToFocus = inputs[this.currentRow * columnKeys.length + this.currentCol]
        this.inputDomToFocus(event, inputToFocus, inputs)
      }
    },
    // 处理左箭头事件
    handleArrowLeft(event, inputs, columnKeys) {
      if (this.currentCol > 0) {
        this.currentCol--
        const inputToFocus = inputs[this.currentRow * columnKeys.length + this.currentCol]
        this.inputDomToFocus(event, inputToFocus, inputs)
      }
    },
    // 处理下箭头事件
    handleArrowDown(event, inputs, columnKeys) {
      // 如果是number类型的输入框，不做后续处理，上下键是加减数字的
      const inputToFocus1 = inputs[this.currentRow * columnKeys.length + this.currentCol]
      console.log(inputToFocus1)
      if (inputToFocus1 && inputToFocus1.nodeName === 'INPUT' && inputToFocus1.type == 'number') {
        return
      }
      if (this.currentRow < this.TableConfig.tableData.length - 1) {
        this.currentRow++
        const inputToFocus = inputs[this.currentRow * columnKeys.length + this.currentCol]
        this.inputDomToFocus(event, inputToFocus, inputs)
      } else {
        this.currentRow++
        this.addRow(this.TableConfig.tableData, this.TableConfig.tableData.length - 1)
        setTimeout(() => {
          inputs = this.handleInputs().inputs
          const inputToFocus = inputs[this.currentRow * columnKeys.length + this.currentCol]
          this.inputDomToFocus(event, inputToFocus, inputs)
        }, 200)
      }
    },
    // 找到焦点focus
    inputDomToFocus(event, inputToFocus) {
      if (inputToFocus && inputToFocus.nodeName === 'INPUT') {
        // 普通输入框直接聚焦
        inputToFocus.focus()
      } else if (inputToFocus && inputToFocus.className.includes('el-select')) {
        const minInput = inputToFocus.getElementsByTagName('input')[0]
        // el-select选择框，找到里面的input聚焦，并且添加border效果
        minInput.style.outline = '1px solid #1890ff'
        minInput.focus()
        // 设置监听函数，方便移除
        const eventLister = () => {
          minInput.style.outline = ''
          // 移除监听事件
          minInput.removeEventListener('blur', eventLister)
          minInput = null
        }
        // 监听minInput元素，失去焦点时去掉border效果
        minInput.addEventListener('blur', eventLister)
      } else if (inputToFocus && inputToFocus.className.includes('el-input')) {
        const minInput = inputToFocus.getElementsByTagName('input')[0]
        // el-input输入框，找到里面的input后聚焦
        minInput.focus()
      }
      event.preventDefault()
    },

    // 找到当前tr的下标
    getTrIndex(tr) {
      let tableBox
      if (this.tableId) {
        let tableIdName = this.tableId
        tableBox = document.getElementById(tableIdName)
      } else {
        tableBox = document.getElementById('tableId')
      }
      let allTr = tableBox.getElementsByTagName('tr')
      if (tr.nodeName.toLowerCase() == 'tr') {
        for (var i = 0; i < allTr.length; i++) {
          if (allTr[i] === tr) {
            if (i >= 0) {
              this.tableIndex = i - 1
            }
          }
        }
      }
    },
    // 处理提示框的数据显示 及 替换表格内当前选中的数据
    handleTipBox(downState) {
      if (downState == 'ArrowDown' && this.tipSpList.mark != this.tipSpList.listData.length - 1) {
        // 如果按键向下 且 当前选中数据为最后一个时 当前选中数据+1
        this.tipSpList.mark++
      } else if (downState == 'ArrowUp' && this.tipSpList.mark != 0 && this.tipSpList.mark != -1) {
        // 如果按键向上 且 当前选中数据不是第一个也不是未选则时 当前选中数据-1
        this.tipSpList.mark--
      } else if (downState == 'ArrowUp' && this.tipSpList.mark == -1) {
        // 如果按键向上 且 当前选中数据是未选则时 当前选中数据为提示框的最后一条数据
        this.tipSpList.mark = this.tipSpList.listData.length - 1
      }
      // 获取提示框table 得到当前选中行自动滚动到可视区域
      let cptbl = document.getElementById('tipTable')
      let ptr = cptbl.rows[this.tipSpList.mark]
      // 把当前选择的行滚动到可视区域
      ptr.scrollIntoViewIfNeeded()
      // 上下键选则数据时，存储当前行数据
      this.selecSptListData = this.tipSpList.listData[this.tipSpList.mark]
      // 在上下键选择时，自动替换当前行的数据（会存在一直提示选择重复商品问题）
      // this.$emit('onHandleSpData', this.TableConfig.tableData, this.tableIndex, this.selecSptListData)
    },
    // 处理提示框按下回车后操作
    handleTipBoxEnter(tdRight, downState) {
      if (this.companyId) {
        this.tipSpList.displaySta = 'none' // 隐藏提示框
        this.selectInput(tdRight, 'tdRight') // 选中当前输入框的下一个
        if (downState == 'Enter') {
          this.onSelectCommodity(this.selecSptListData)
        }
      } else {
        this.$elMessage({
          showClose: true,
          message: '价格跟踪或折扣跟踪模式下请先选择客户！',
          type: 'error',
          iconClass: 'el-icon-warning-outline',
          duration: 3000,
        })
      }
      // this.tipSpList.displaySta = 'none' // 隐藏提示框
      // this.selectInput(tdRight, 'tdRight') // 选中当前输入框的下一个
      // if (downState == 'Enter') {
      //   if (this.TableConfig.tableData.length > 1) {
      //     for (let i = 0; i < this.TableConfig.tableData.length; i++) {
      //       if (this.TableConfig.tableData[i].goodsId === this.selecSptListData.id) {
      //         this.$elMessage({
      //           showClose: true,
      //           message: '不能重复选择商品！',
      //           type: 'error',
      //           iconClass: 'el-icon-warning-outline',
      //           duration: 3000,
      //         })
      //         // for (const key in this.TableConfig.tableData[i]) {
      //         //   this.TableConfig.tableData[i][key] = ''
      //         // }
      //         return
      //       }
      //     }
      //   }
      //   // 在获取商品后，事件发射到父组件通知父组件来处理数据字段名不统一问题
      //   this.$emit('onHandleSpData', this.TableConfig.tableData, this.tableIndex, this.selecSptListData)
      // }
    },
    // 判断键盘事件 选择相应的节点
    nodeSelect(tdRight, tdLeft, tr, trUp, trDown, myindex) {
      // 如果是按下回车键
      if (event.key == 'Enter') {
        // 用当前点击的列标和当前行有多少下标做对比，如果是最后一列
        if (myindex == tr.children.length - 1) {
          // if (myindex == 11) {
          // 如果当前选择的行不是整个表格的最后一行
          if (this.tableIndex != this.TableConfig.tableData.length - 1) {
            // 则把下一行需要选择的那一列传递给选择输入框方法
            // this.selectInput(trDown.children[3])
            this.selectInput(trDown.children[this.tipTbaleIndex])
          }
        } else {
          this.selectInput(tdRight, 'tdRight')
        }
      }
      // 如果是按向上键
      else if (event.key == 'ArrowUp') {
        // 判断当前选择的行不是第一行
        if (this.tableIndex != 0) {
          // this.selectInput(trUp.children[myindex])
          // 被处理过的trUp是一个数组,所以只需要直接找到这个数据的对应的值,不用通过trUp.children找
          this.selectInput(trUp[myindex])
        }
      }
      // 如果是按向右键
      else if (event.key == 'ArrowRight') {
        // 用当前点击的列标和当前行有多少下标做对比，如果是最后一列
        if (myindex == tr.children.length - 1) {
          // if (myindex == 11) {
          // 如果当前选择的行不是整个表格的最后一行
          if (this.tableIndex != this.TableConfig.tableData.length - 1) {
            // 则把下一行需要选择的那一列传递给选择输入框方法
            // this.selectInput(trDown.children[3])
            this.selectInput(trDown.children[this.tipTbaleIndex])
          }
        } else {
          this.selectInput(tdRight, 'tdRight')
        }
      }
      // 如果是按向下键
      else if (event.key == 'ArrowDown') {
        // 判断当前选择的行不是最后一行
        if (this.tableIndex != this.TableConfig.tableData.length - 1) {
          // this.selectInput(trDown.children[myindex])
          // 被处理过的trDown是一个数组,所以只需要直接找到这个数据的对应的值,不用通过trDown.children找
          this.selectInput(trDown[myindex])
        }
      }
      // 如果是按向左键
      else if (event.key == 'ArrowLeft') {
        this.selectInput(tdLeft, 'tdLeft')
      }
    },
    // 选中当前输入框
    selectInput(selectNode, mark) {
      // 判断如果当前td下是input的话就选中，如果不是就继续寻找下一个td
      if (this.findinput(selectNode)) {
        let nextInput = this.findinput(selectNode)
        // event.preventDefault() // 阻止默认行为
        nextInput.select()
        nextInput.scrollIntoViewIfNeeded()
      } else {
        if (mark == 'tdRight') {
          let nextTd = selectNode.nextElementSibling
          this.selectInput(nextTd, 'tdRight')
        } else if (mark == 'tdLeft') {
          let nextTd = selectNode.previousElementSibling
          this.selectInput(nextTd, 'tdLeft')
        }
      }
    },
    // 遍历找到td
    findtd(elm) {
      if (elm && elm.parentNode) {
        if (elm.parentNode.nodeName == 'TD') {
          return elm.parentNode
        } else {
          this.findtd(elm.parentNode)
        }
      }
    },
    // 遍历找到input
    findinput(elm) {
      if (elm && elm.children[0]) {
        if (elm.children[0].nodeName == 'INPUT') {
          return elm.children[0]
        } else {
          this.findinput(elm.children[0])
        }
      }
    },
    // 键盘抬起时触发
    gridOnKeyUp(event) {
      return
      event.preventDefault() // 阻止默认行为
      let obj = event.target // 当前触发的input
      let td = this.findtd(obj) // 当前input所在的td
      let tr = td.parentNode // 当前td所在的tr
      // 得到当前页面所显示的td元素
      let trTd = tr.getElementsByClassName('tdDom')
      let myindex = Array.prototype.indexOf.call(trTd, td) // 判断当前所触发元素在当前行的第几列
      // 判断当前所触发的节点 位于表格的第几行
      this.getTrIndex(tr)
      // 如果触发的是输入框 且 触发的是商品名称列数据时
      // if (obj.nodeName == 'INPUT' && myindex == 3) {
      if (obj.nodeName == 'INPUT' && myindex == this.tipTbaleIndex) {
        // 判断如果是向下/向上/退格/删除键时 阻止按键的默认行为
        if (event.key == 'ArrowDown' || event.key == 'ArrowUp' || event.key == 'Backspace' || event.key == 'Delete') {
          event.preventDefault()
        }
        // 这个是做输入时数据智能匹配的，现在只用默认展示历史记录的三条，所以暂不使用
        // else {
        //   //寻找对应的匹配索引
        //   let oldvalue = obj.value
        //   // 输入框非空判断
        //   if (obj.value != '') {
        //     let pipei_index = this.findProductIndex(obj.value)
        //     // 修改提示框选中行
        //     this.tipSpList.mark = pipei_index
        //     //如果有匹配的行
        //     if (pipei_index >= 0) {
        //       // 获取提示框当前选中行数据
        //       this.selecSptListData = this.tipSpList.listData[pipei_index]
        //       // // 获取提示框当前选中行数据
        //       // let pipei_product = this.tipSpList.listData[pipei_index];
        //       // 得到与输入框相匹配的值
        //       let inputValue = this.findProduct(obj.value, this.selecSptListData)
        //       // 商品编码赋值
        //       if (inputValue != '') {
        //         let productcd = inputValue
        //         obj.value = productcd
        //         obj.select()
        //         obj.selectionStart = oldvalue.length
        //       }
        //     }
        //   }
        // }
      }
    },
    // 找到输入框的值在提示框的哪一行
    findProductIndex(inputvalue) {
      let length = this.tipSpList.listData.length
      for (let i = 0; i < length; i++) {
        let item = this.tipSpList.listData[i]
        if (item.goodsName.indexOf(inputvalue) == 0) {
          return i
        }
        if (item.goodsCode.indexOf(inputvalue) == 0) {
          return i
        }
        if (item.goodsName.indexOf(inputvalue) == 0) {
          return i
        }
        // if (item.specs.indexOf(inputvalue) == 0) {
        //   return i
        // }
        if (item.baseUnit.indexOf(inputvalue) == 0) {
          return i
        }
        if (item.warehouse.indexOf(inputvalue) == 0) {
          return i
        }
        if (item.number.indexOf(inputvalue) == 0) {
          return i
        }
        if (item.unitPrice.indexOf(inputvalue) == 0) {
          return i
        }
        if (item.money.indexOf(inputvalue) == 0) {
          return i
        }
        if (item.arrivalDate.indexOf(inputvalue) == 0) {
          return i
        }
        if (item.arrivalQty.indexOf(inputvalue) == 0) {
          return i
        }
        // if (item.unArrivalQty.indexOf(inputvalue) == 0) {
        //   return i
        // }
        // if (item.remarks.indexOf(inputvalue) == 0) {
        //   return i
        // }
      }
      return -1
    },
    // 找到输入框的值与提示框匹配的值
    findProduct(inputvalue, pipei_product) {
      var value = ''
      for (const key in pipei_product) {
        if (pipei_product[key].indexOf(inputvalue) == 0) {
          this.value = pipei_product[key]
          break
        }
      }
      return this.value
    },

    // 获取提示框当前选择的行数据
    activeMark(index) {
      this.tipSpList.mark = index
      this.selecSptListData = this.tipSpList.listData[index]
    },
    // 替换展示提示框当前选择的行数据
    selectMark() {
      if (this.companyId) {
        this.tipSpList.displaySta = 'none' // 隐藏提示框
        this.onSelectCommodity(this.selecSptListData)
      } else {
        this.$elMessage({
          showClose: true,
          message: '价格跟踪或折扣跟踪模式下请先选择客户！',
          type: 'error',
          iconClass: 'el-icon-warning-outline',
          duration: 3000,
        })
      }
    },
    // 替换价格列表展示提示框当前选择的行数据
    selectMarkPrice(item) {
      this.tipPriceList.displaySta = 'none' // 隐藏提示框
      this.TableConfig.tableData[this.tableIndex][this.tipPriceList.inputName] = item.price
      if (this.tipPriceList.inputName === 'salePrice') {
        this.handlePrice(this.tableIndex)
      } else if (this.tipPriceList.inputName === 'discountRate') {
        this.handleDiscountRate(this.tableIndex)
      }
    },
    // 替换价格列表展示提示框当前选择的行数据
    selectMarkDiscount(item) {
      this.tipDiscountList.displaySta = 'none' // 隐藏提示框
      this.TableConfig.tableData[this.tableIndex][this.tipDiscountList.inputName] = item.discountRate
      if (this.tipPriceList.inputName === 'discountRate') {
        this.handleDiscountRate(this.tableIndex)
      }
    },
    // 添加一行数据
    addRow(event, index) {
      let obj = {
        visible: false,
        dvisible: false,
      }

      for (const key in this.TableConfig.columnData) {
        if (key == 'xghStorehouseId') {
          obj[key] = this.storehouseId
        } else if (key == 'discountRate') {
          obj[key] = this.discountRate || 100
        } else if (key == 'taxRate') {
          obj[key] = parseInt(this.taxRate)
        } else if (key !== 'idx') {
          obj[key] = ''
        }
      }
      for (let i = 0; i < this.TableConfig.tableData.length; i++) {
        if (index === i) {
          this.TableConfig.tableData.splice(i + 1, 0, obj)
        }
      }
      // let trDown = event.target.parentNode.parentNode.parentNode.parentNode.nextElementSibling // 当前选中的下一行
      // setTimeout(() => {
      // this.findinput(trDown.children[3]).select()
      // }, 300)
      this.$emit('onAddRow', this.TableConfig.tableData)
    },
    // 复制当前行数据
    copyRow(event, index) {
      // 获取当前行的数据
      const currentRowData = this.TableConfig.tableData[index]
      // 创建新对象，复制当前行的数据
      const newRowData = { ...currentRowData }
      // 插入新行到当前行的下一行
      this.TableConfig.tableData.splice(index + 1, 0, newRowData)
      // 触发事件通知父组件
      this.$emit('onCopyRow', this.TableConfig.tableData)
    },
    // 删除当前行数据
    deleteRow(index) {
      if (this.TableConfig.tableData.length === 1) {
        let obj = {}
        let item = this.TableConfig.tableData[0]
        for (const key in this.TableConfig.columnData) {
          if (['idx', 'discountRate', 'xghStorehouseId'].includes(key)) {
            obj[key] = item[key]
          } else {
            obj[key] = ''
          }
        }
        this.TableConfig.tableData = [obj]
        return
      }
      this.TableConfig.tableData.splice(index, 1)
      this.$emit('onDeleteRow', this.TableConfig.tableData)
    },
  },
}
</script>

<style lang="scss" scoped>
.table_div {
  width: 100%;
  height: 100%;
  box-sizing: border-box;
  position: relative;
  overflow: auto;

  &::-webkit-scrollbar {
    width: 10px;
    height: 10px;
  }

  &::-webkit-scrollbar-thumb {
    background: #c9c9c9;
  }

  &::-webkit-scrollbar-track {
    background: #e5e5e5;
  }

  ::v-deep .el-select {
    height: 100%;
    box-sizing: border-box;
    display: table;

    .el-input {
      height: 100%;

      .el-input__inner {
        height: 100%;
        font-size: 12px;
        border-radius: 0;
        border: none;
      }

      .el-input__suffix {
        height: 100%;
        display: flex;
        align-items: center;
      }

      .el-textarea {
        height: 100%;
        // width: 30px;
      }
    }
  }
}

.pop {
  ::v-deep .el-input {
    height: 100%;
    // padding: 0 3px;

    .el-input__inner {
      height: 100%;
      font-size: 12px;
      border: none;
      border-radius: 0;
    }
  }
}

.table_style {
  width: 100%;
  height: 100%;
  border-spacing: 0;
  border-collapse: unset;

  tbody {
    display: block;
    // height: 100%;
    height: calc(100% - 60px);
    overflow-y: scroll;

    tr {
      position: relative;
      background: #fff;
      box-sizing: border-box;
      height: 30px;

      td {
        position: relative;
        text-align: center;
        border-right: 1px solid #e3e3e3;
        border-bottom: 1px solid #e3e3e3;
        height: 30px;
        box-sizing: border-box !important;
        padding: 0;

        input {
          border: none; //1px solid #dcdfe6;
          // height: 24px;
          // width: 90px;
          // padding: 0 5px;
          height: 100%;
          width: 100%;
          box-sizing: border-box;
          color: #666;
          font-size: 12px;

          // margin: 4px 0;
          &:focus {
            outline: none;
            border: 1px solid #1893fc;
          }

          &:focus + i {
            transform: rotate(180deg);
            transition: 0.3s all;
          }

          &::placeholder {
            color: #c9c9c9;
          }
        }

        ::v-deep .el-input {
          width: 100%;
          height: 100%;
          display: table;

          .el-input__inner {
            width: 100%;
            height: 100%;
            padding: 0 5px 0 5px;
            font-size: 12px;
            color: #666;
            border-radius: 0;
          }
        }

        .inpu_checkbox {
          width: 50px;
          height: 16px;
          background: pink;
          border-color: #dcdfe6;
        }

        ::v-deep .el-date-editor {
          width: 100%;
          height: 100%;

          .el-input__inner {
            width: 100%;
            height: 100%;
            padding: 0 25px 0 5px;
            font-size: 12px;
            color: #666;
            border-radius: 0;
            border: none;
          }

          .el-input__prefix {
            left: unset;
            right: 0 !important;

            .el-input__icon {
              line-height: 24px;
              font-size: 12px;
            }
          }

          .el-input__suffix {
            display: none;
          }
        }

        ::v-deep .el-input.is-disabled {
          .el-input__inner {
            background-color: #ededed;
            border: 1px solid #e3e3e3;

            color: #999;
          }

          .el-input__icon {
            color: #999;
          }
        }

        .click_p {
          // position: absolute;
          width: 44px;
          height: 100%;
          background: #1893fc;
          font-size: 12px;
          color: #fff;
          // right: 0;
          // top: 0;
          margin: 0;
          // display: inline-block;
          display: flex;
          justify-content: center;
          align-items: center;
          cursor: pointer;
        }

        .select_input {
          height: 21px;
          line-height: 21px;
          position: absolute;
          right: 6px;
          font-size: 12px;
          color: #c0c4cc;
          background: #fff;
          margin: 6px 0;
          padding: 0 2px;
        }

        .select_option,
        .select_option_ck {
          position: absolute;
          top: 22px;
          left: 5px;
          z-index: 999;
          min-width: 90px;
          max-height: 200px;
          background: #fff;
          display: flex;
          flex-direction: column;
          padding: 6px 0;
          border: 1px solid #e4e7ed;
          box-shadow: 0 2px 12px 0 rgb(0 0 0 / 10%);
          border-radius: 4px;
          display: none;
          overflow: auto;

          &::-webkit-scrollbar {
            width: 10px;
            height: 10px;
          }

          &::-webkit-scrollbar-thumb {
            background: #c9c9c9;
          }

          &::-webkit-scrollbar-track {
            background: #e5e5e5;
          }

          li {
            width: 100%;
            height: 34px;
            line-height: 34px;
            list-style-type: none;
            font-size: 14px;
            color: #666;
            background-color: #fff;
            padding: 0 20px;
            text-align: left;
            white-space: nowrap;

            &:hover {
              background-color: #f5f7fa;
            }
          }

          .select_li {
            color: #409eff;
            background-color: #f5f7fa;
            font-weight: 700;
          }
        }

        p {
          // font-size: 0.225014rem;
          font-size: 12px;
          color: #666;
          margin: 0;
          padding: 0 5px;
          text-align: left;
        }

        &:last-child {
          border-right: none;
        }
      }

      .first_td {
        cursor: pointer;
        display: flex;
        align-items: center;
        justify-content: center;
        padding: 0 !important;

        .first_td_button1 {
          width: 100% !important;
          display: flex;
          justify-content: center;

          p {
            width: 20px;
            height: 20px;
            border-radius: 50%;
            border: 1px solid #1893fc;
            display: flex;
            align-items: center;
            justify-content: center;
            color: #1893fc;
            font-size: 12px;
            cursor: pointer;
            margin: 0;

            &:first-child {
              margin-right: 3px;
            }

            &:last-child {
              margin-left: 3px;
              border-color: #fb1919;
              color: #fb1919;

              span {
                margin-top: -0.056254rem;
              }
            }
          }
        }

        .first_td_button {
          width: 100% !important;
          display: flex;
          justify-content: center;

          i {
            font-size: 23px;
            // height: 24px;
            padding: 3.5px 0;

            &:first-child {
              color: #1893fc;
            }

            &:last-child {
              color: #fd5050;
            }
          }
        }

        .first_td_p {
          width: 100%;
          height: 30px;
          line-height: 30px;
          // font-size: 0.225014rem;
          font-size: 12px;
          color: #666;
          text-align: center;
          margin: 0;
        }
      }
    }

    &::-webkit-scrollbar {
      width: 10px;
      height: 10px;
    }

    &::-webkit-scrollbar-thumb {
      background: #c9c9c9;
    }

    &::-webkit-scrollbar-track {
      background: #e5e5e5;
    }
  }

  .first_tr {
    width: 100%;
    height: 30px;
    background: #ededed;
    box-sizing: border-box;

    th {
      border-right: 1px solid #e3e3e3;
      border-bottom: 1px solid #e3e3e3;

      p {
        margin: 0;
        color: #666;
        // font-size: 0.225014rem;
        font-size: 12px;
        text-align: center;
      }

      ::v-deep .el-input {
        .el-input__inner {
          padding-left: 3px;
          border: #707070 solid 1px;
          border-radius: 0;
        }
      }
    }

    .star {
      color: #fb1919;
      margin-right: 0.056254rem;
    }

    :last-child {
      border-right: none;
    }
  }

  .last_tr {
    width: 100%;
    height: 30px;
    background: #ededed;
    box-sizing: border-box;

    td {
      box-sizing: border-box;
      padding: 0 0.187512rem;
      border-right: none;

      p {
        width: 100%;
        // font-size: 0.225014rem;
        font-size: 12px;
        color: #666;
        margin: 0;
      }

      &:first-child {
        text-align: center;
      }
    }
  }

  thead {
    display: block;
    height: 30px;
  }

  tfoot {
    display: block;
    height: 30px;
    position: absolute;
    bottom: 0;
  }
}

.active_backGround {
  background: #e3f6ff !important;
}

.tip_box {
  min-width: 150px;
  padding: 12px;
  overflow: auto;
  position: absolute;
  background: #fff;
  border: 1px solid #ebeef5;
  box-shadow: 0 2px 12px 0 rgb(0 0 0 / 10%);
  z-index: 999;
  transition: all 0.3s;

  .tip_table {
    width: 100%;
    height: 100%;
    background: #fff;
    border-spacing: 0;

    tr {
      font-size: 12px;
      color: #666;
    }

    tr {
      th,
      td {
        height: 30px;
        text-align: center;
        padding: 0 15px;
        border-top: 1px solid #e3e3e3;
        border-right: 1px solid #e3e3e3;

        &:first-child {
          border-left: 1px solid #e3e3e3;
        }
      }

      th {
        background: #ededed;
      }
    }

    td {
      padding: 0 3px;
      height: 30px;
      white-space: nowrap;
      text-align: left;
      margin: 0;
      border: none;
      color: #666;
      // font-size: 0.225014rem;
      font-size: 0.2rem;
      cursor: pointer;
    }
  }

  .add_icon {
    width: 100%;
    height: 30px;
    background: #ededed;
    margin: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 14px;
    color: #666;
    border: 1px solid #e3e3e3;
    cursor: pointer;
  }

  .active_mark {
    background: #e3f6ff;
  }

  &::-webkit-scrollbar {
    width: 10px;
    height: 10px;
  }

  &::-webkit-scrollbar-thumb {
    background: #c9c9c9;
  }

  &::-webkit-scrollbar-track {
    background: #e5e5e5;
  }
}

.tip_price_box {
  min-width: 150px;
  padding: 12px;
  overflow: auto;
  position: absolute;
  top: 0;
  left: 0;
  background: #fff;
  border: 1px solid #ebeef5;
  box-shadow: 0 2px 12px 0 rgb(0 0 0 / 10%);
  z-index: 999;
  transition: all 0.3s;

  .tip_table {
    width: 100%;
    height: 100%;
    background: #fff;
    border-spacing: 0;
    border-left: 1px solid #e3e3e3;
    border-bottom: 1px solid #e3e3e3;

    tr {
      font-size: 12px;
      color: #666;
    }

    tr {
      td {
        height: 30px;
        text-align: center;
        padding: 0 15px;
        border-top: 1px solid #e3e3e3;
        border-right: 1px solid #e3e3e3;
      }
    }

    td {
      padding: 0 0.112507rem;
      height: 30px;
      white-space: nowrap;
      text-align: left;
      margin: 0;
      border: none;
      color: #666;
      // font-size: 0.225014rem;
      font-size: 0.2rem;
      cursor: pointer;
    }
  }

  .active_mark {
    background: #e3f6ff;
  }

  &::-webkit-scrollbar {
    width: 10px;
    height: 10px;
  }

  &::-webkit-scrollbar-thumb {
    background: #c9c9c9;
  }

  &::-webkit-scrollbar-track {
    background: #e5e5e5;
  }
}

.price_item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 6px 10px;
  border-bottom: 1px solid #eeeeee;
  cursor: pointer;
}

.price_text {
}

.price_value {
}

.resizer {
  position: absolute;
  top: 0;
  right: 0;
  width: 3px;
  height: 100%;
  cursor: col-resize;
}

.addFormula {
  .extendView {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 80px;

    .title {
      flex-shrink: 0;
      margin-right: 10px;
    }
  }

  .dialog_bottom {
    width: 100%;
    height: 80px;
    display: flex;
    align-items: center;
    justify-content: center;

    .el-button {
      width: 80px;
    }
  }

  ::v-deep .el-dialog {
    .el-dialog__body {
      padding: 10px 30px;
    }
  }
}

.singleLine {
  overflow: hidden;
  -webkit-line-clamp: 1;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-box-orient: vertical;
}
</style>
